Qt中如何使窗口隐藏/最小化到托盘

Qt中如何实现自己的托盘功能,Qt自带的demo也很明了,这里我们就来实现自己的一个托盘。。。

功能:窗口最小化后或者点击“hide”按钮将窗口隐藏到托盘。

    通常最小化的窗口会在任务栏上显示一个按钮。当用户按一下这个按钮,窗口就还原了。这是一个被大多数桌面环境,比如WindowsKDEGNOME所采用的普遍设计。不过,因为任务栏通常只是桌面边上一小行,容纳不了很多按钮,用户通常希望把那些不常用的程序隐藏起来,只在通知栏显示一个小图标,要使用的时候再点击那个小图标恢复窗口。这种作法最典型的例子是QQWinamp

最基本的思路是拦截窗口的最小化事件changeEvent(),通过重写changeEvent()即可。

“hide”按钮的方式,是通过信号--槽来实现。

--------------------------------------------------------------------

  void TrayMenu::createActions()
  {
     //创建托盘项
     action_show = new QAction(this);
     action_quit = new QAction(this);
     action_login_home = new QAction(this);
     action_help = new QAction(this);
     action_about = new QAction(this);
     action_check_update = new QAction(this);
     action_setting = new QAction(this);

 

     //设置托盘项图标

     action_show->setIcon(QIcon(":/icon/open"));
     action_login_home->setIcon(QIcon(":/icon/home"));
     action_help->setIcon(QIcon(":/icon/help"));
     action_about->setIcon(QIcon(":/icon/about"));
     action_check_update->setIcon(QIcon(":/icon/update"));
     action_setting->setIcon(QIcon(":/icon/set"));
     action_quit->setIcon(QIcon(":/icon/quit"));

     //加载图片和提示

QIcon icon(":/images/sysTray.png");
systemTray = new QSystemTrayIcon(this);
systemTray->setIcon(icon);
systemTray->setToolTip("Hello, this is system tray!");

 注意:这里特别提醒,如果你的应用程序要移植到别的机器上,而且这个机器没有装Qt,QIcon的图片格式最好用png,而不要用ico等格式,否则托盘图标不能显示,会很麻烦。


     //设置托盘想文本

     action_show->setText(QString("显示"));
     action_quit->setText(QString("退出"));
     action_login_home->setText(QString("登录网页"));

     action_help->setText(QString("帮助"));
     action_about->setText(QString("关于"));

     action_check_update->setText(QString("检查更新"));

     action_setting->setText(QString("设置"));

 

     //添加菜单项
     this->addAction(action_show);
     this->addAction(action_setting);
     this->addAction(action_login_home);
     this->addSeparator();
     this->addAction(action_help);
     this->addAction(action_about);
     this->addAction(action_check_update);
     this->addSeparator();
     this->addAction(action_quit);

     action_setting->setVisible(false);

 

     //设置信号连接(这里仅列举连接显示窗口的信号)
     QObject::connect(action_show, SIGNAL(triggered(bool)), this, SIGNAL(showWidget()));
 }

 

  LoginDialog::LoginDialog(QWidget *parent) : QDialog(parent)
  {

     QSystemTrayIcon *system_tray = new QSystemTrayIcon();

     //放在托盘提示信息、托盘图标

     system_tray ->setToolTip(QString("我就是托盘"));
     system_tray ->setIcon(QIcon(":/icon/login"));

     TrayMenu *tray_menu = new TrayMenu();
     system_tray->setContextMenu(tray_menu);

     //点击托盘执行的事件
      connect(system_tray , SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(iconIsActived(QSystemTrayIcon::ActivationReason)));
     connect(tray_menu, SIGNAL(showWidget()), this, SLOT(showNormal()));

     //显示托盘
     system_tray->show();

    //托盘显示提示信息

    system_tray->showMessage(QString("托盘标题"), QString("托盘显示内容"));

  }

 

  void LoginDialog::iconIsActived(QSystemTrayIcon::ActivationReason reason)
  {
     switch(reason)
     {
     //点击托盘显示窗口
     case QSystemTrayIcon::Trigger:
      {
        showNormal();
        break;
      }   
     //双击托盘显示窗口
     case QSystemTrayIcon::DoubleClick:
     {
       showNormal();
       break; 
                
     default:
      break;
     }
  }

 

  OK,这样我们的托盘功能就Over了!

=============================================================================

另://关闭到托盘
void Widget::closeEvent(QCloseEvent *e)
{
    e->ignore();
    this->hide();
}

//最小化到托盘
void Widget::changeEvent(QEvent *e)
{
    if((e->type()==QEvent::WindowStateChange)&&this->isMinimized())
    {
        QTimer::singleShot(100, this, SLOT(close()));
    }
}

或者(me)

//点击窗口的“最小化"按钮会调用此函数(系统默认)---已实现
void maxLinksGuard::changeEvent(QEvent * event )
{
    if(event->WindowStateChange)
    {
switch(this->windowState())
{
//点击“最小化”按钮
case Qt::WindowMinimized:
                 this->hide();
this->setWindowFlags(Qt::Tool);//隐藏任务栏上图标
systemTray->show();//显示托盘
systemTray->showMessage(windowTitle(),"Here is system,double click will show!");//提示
event->ignore();
                 break;
           default:
                 break;
        }
    }
}

//托盘图标事件--------已实现
void maxLinksGuard::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason) 
{
//单击托盘
case QSystemTrayIcon::Trigger:
{
if(!this->isVisible())
{
this->setWindowFlags(Qt::Window); //显示之前恢复
showNormal();
}
else
{
hide();
}
break;
}
//双击托盘---貌似不起作用
case QSystemTrayIcon::DoubleClick:
{
if(!this->isVisible())
{
this->setWindowFlags(Qt::Window); //显示之前恢复
showNormal();
}
else
{
hide();
}
break;
}
case QSystemTrayIcon::MiddleClick:
{
break;
}
default: ;
}
}

//点击窗口的“关闭”按钮触发closeEvent事件(关闭应用程序)----已实现
void maxLinksGuard::closeEvent(QCloseEvent *event)  
{  
    if (this->isVisible())  
    {  
QMessageBox::critical(NULL,QObject::tr("Prompt:"),QObject::tr("Are you sure you want to kill/stop the MaxLinksGuard?"));
        event->ignore();  
    }  
    else  
{
event->accept();  
}
        
}  


===========================================================

托盘图标,一个自己脑子出现很久的词,可惜自己都没动手去实现。最近看见的,听见的多了,自己也感兴趣就弄弄了,感觉还蛮简单了。

贴出效果图:

 

 

 

那么多功能,其实就一个类就搞定了,那就是QSystemTrayIcon

 头文件(主要 1.声明菜单相关动作 2.声明系统托盘对象,以及相关托盘槽函数 3.关闭事件)

  1. #ifndef SYSTEMTRAYICON_H  
  2. #define SYSTEMTRAYICON_H  
  3.   
  4. #include <QMainWindow>  
  5. #include <QMenu>  
  6. #include <QSystemTrayIcon>  
  7. #include <QCloseEvent>  
  8. namespace Ui {  
  9.     class SystemTrayIcon;  
  10. }  
  11.   
  12. class SystemTrayIcon : public QMainWindow  
  13. {  
  14.     Q_OBJECT  
  15.   
  16. public:  
  17.     explicit SystemTrayIcon(QWidget *parent = 0);  
  18.     ~SystemTrayIcon();  
  19.   
  20.     void CreatTrayMenu();  
  21.     void CreatTrayIcon();  
  22.   
  23.     QSystemTrayIcon *myTrayIcon;  
  24.   
  25.     QMenu *myMenu;  
  26.   
  27.     QAction *miniSizeAction;  
  28.     QAction *maxSizeAction;  
  29.     QAction *restoreWinAction;  
  30.     QAction *quitAction;  
  31.   
  32. private:  
  33.     Ui::SystemTrayIcon *ui;  
  34.   
  35. public slots:  
  36.     void iconActivated(QSystemTrayIcon::ActivationReason reason);  
  37.   
  38. protected:  
  39.     void closeEvent(QCloseEvent *event);  
  40.   
  41. };  
  42.   
  43. #endif // SYSTEMTRAYICON_H  


 

 源文件(1.创建上下文菜单 2.创建系统托盘,实现相关功能)---From  Qt  Assistant

 #include <QtGui>

 #include "window.h"

 Window::Window()
 {
     createIconGroupBox();
     createMessageGroupBox();

     iconLabel->setMinimumWidth(durationLabel->sizeHint().width());

     createActions();
     createTrayIcon();

     connect(showMessageButton, SIGNAL(clicked()), this, SLOT(showMessage()));
     connect(showIconCheckBox, SIGNAL(toggled(bool)),
             trayIcon, SLOT(setVisible(bool)));
     connect(iconComboBox, SIGNAL(currentIndexChanged(int)),
             this, SLOT(setIcon(int)));
     connect(trayIcon, SIGNAL(messageClicked()), this, SLOT(messageClicked()));
     connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
             this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

     QVBoxLayout *mainLayout = new QVBoxLayout;
     mainLayout->addWidget(iconGroupBox);
     mainLayout->addWidget(messageGroupBox);
     setLayout(mainLayout);

     iconComboBox->setCurrentIndex(1);
     trayIcon->show();

     setWindowTitle(tr("Systray"));
     resize(400, 300);
 }

 void Window::setVisible(bool visible)
 {
     minimizeAction->setEnabled(visible);
     maximizeAction->setEnabled(!isMaximized());
     restoreAction->setEnabled(isMaximized() || !visible);
     QDialog::setVisible(visible);
 }

 void Window::closeEvent(QCloseEvent *event)
 {
     if (trayIcon->isVisible()) {
         QMessageBox::information(this, tr("Systray"),
                                  tr("The program will keep running in the "
                                     "system tray. To terminate the program, "
                                     "choose <b>Quit</b> in the context menu "
                                     "of the system tray entry."));
         hide();
         event->ignore();
     }
 }

 void Window::setIcon(int index)
 {
     QIcon icon = iconComboBox->itemIcon(index);
     trayIcon->setIcon(icon);
     setWindowIcon(icon);

     trayIcon->setToolTip(iconComboBox->itemText(index));
 }

 void Window::iconActivated(QSystemTrayIcon::ActivationReason reason)
 {
     switch (reason) {
     case QSystemTrayIcon::Trigger:
     case QSystemTrayIcon::DoubleClick:
         iconComboBox->setCurrentIndex((iconComboBox->currentIndex() + 1)
                                       % iconComboBox->count());
         break;
     case QSystemTrayIcon::MiddleClick:
         showMessage();
         break;
     default:
         ;
     }
 }

 void Window::showMessage()
 {
     QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::MessageIcon(
             typeComboBox->itemData(typeComboBox->currentIndex()).toInt());
     trayIcon->showMessage(titleEdit->text(), bodyEdit->toPlainText(), icon,
                           durationSpinBox->value() * 1000);
 }

 void Window::messageClicked()
 {
     QMessageBox::information(0, tr("Systray"),
                              tr("Sorry, I already gave what help I could.\n"
                                 "Maybe you should try asking a human?"));
 }

 void Window::createIconGroupBox()
 {
     iconGroupBox = new QGroupBox(tr("Tray Icon"));

     iconLabel = new QLabel("Icon:");

     iconComboBox = new QComboBox;
     iconComboBox->addItem(QIcon(":/images/bad.svg"), tr("Bad"));
     iconComboBox->addItem(QIcon(":/images/heart.svg"), tr("Heart"));
     iconComboBox->addItem(QIcon(":/images/trash.svg"), tr("Trash"));

     showIconCheckBox = new QCheckBox(tr("Show icon"));
     showIconCheckBox->setChecked(true);

     QHBoxLayout *iconLayout = new QHBoxLayout;
     iconLayout->addWidget(iconLabel);
     iconLayout->addWidget(iconComboBox);
     iconLayout->addStretch();
     iconLayout->addWidget(showIconCheckBox);
     iconGroupBox->setLayout(iconLayout);
 }

 void Window::createMessageGroupBox()
 {
     messageGroupBox = new QGroupBox(tr("Balloon Message"));

     typeLabel = new QLabel(tr("Type:"));

     typeComboBox = new QComboBox;
     typeComboBox->addItem(tr("None"), QSystemTrayIcon::NoIcon);
     typeComboBox->addItem(style()->standardIcon(
             QStyle::SP_MessageBoxInformation), tr("Information"),
             QSystemTrayIcon::Information);
     typeComboBox->addItem(style()->standardIcon(
             QStyle::SP_MessageBoxWarning), tr("Warning"),
             QSystemTrayIcon::Warning);
     typeComboBox->addItem(style()->standardIcon(
             QStyle::SP_MessageBoxCritical), tr("Critical"),
             QSystemTrayIcon::Critical);
     typeComboBox->setCurrentIndex(1);

     durationLabel = new QLabel(tr("Duration:"));

     durationSpinBox = new QSpinBox;
     durationSpinBox->setRange(5, 60);
     durationSpinBox->setSuffix(" s");
     durationSpinBox->setValue(15);

     durationWarningLabel = new QLabel(tr("(some systems might ignore this "
                                          "hint)"));
     durationWarningLabel->setIndent(10);

     titleLabel = new QLabel(tr("Title:"));

     titleEdit = new QLineEdit(tr("Cannot connect to network"));

     bodyLabel = new QLabel(tr("Body:"));

     bodyEdit = new QTextEdit;
     bodyEdit->setPlainText(tr("Don't believe me. Honestly, I don't have a "
                               "clue.\nClick this balloon for details."));

     showMessageButton = new QPushButton(tr("Show Message"));
     showMessageButton->setDefault(true);

     QGridLayout *messageLayout = new QGridLayout;
     messageLayout->addWidget(typeLabel, 0, 0);
     messageLayout->addWidget(typeComboBox, 0, 1, 1, 2);
     messageLayout->addWidget(durationLabel, 1, 0);
     messageLayout->addWidget(durationSpinBox, 1, 1);
     messageLayout->addWidget(durationWarningLabel, 1, 2, 1, 3);
     messageLayout->addWidget(titleLabel, 2, 0);
     messageLayout->addWidget(titleEdit, 2, 1, 1, 4);
     messageLayout->addWidget(bodyLabel, 3, 0);
     messageLayout->addWidget(bodyEdit, 3, 1, 2, 4);
     messageLayout->addWidget(showMessageButton, 5, 4);
     messageLayout->setColumnStretch(3, 1);
     messageLayout->setRowStretch(4, 1);
     messageGroupBox->setLayout(messageLayout);
 }

 void Window::createActions()
 {
     minimizeAction = new QAction(tr("Mi&nimize"), this);
     connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));


     maximizeAction = new QAction(tr("Ma&ximize"), this);
     connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));


     restoreAction = new QAction(tr("&Restore"), this);
     connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));


     quitAction = new QAction(tr("&Quit"), this);
     connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
 }

 void Window::createTrayIcon()
 {
     trayIconMenu = new QMenu(this);
     trayIconMenu->addAction(minimizeAction);
     trayIconMenu->addAction(maximizeAction);
     trayIconMenu->addAction(restoreAction);
     trayIconMenu->addSeparator();//添加隔离符
     trayIconMenu->addAction(quitAction);


     trayIcon = new QSystemTrayIcon(this);
     trayIcon->setContextMenu(trayIconMenu);
 }

转:http://blog.sina.com.cn/s/blog_a6fb6cc90101dddb.html

      http://blog.csdn.net/qivan/article/details/7506306

另可参考:http://www.cnblogs.com/csuftzzk/archive/2013/01/25/2877283.html

http://www.qtcn.org/bbs/simple/?t15361.html

http://blog.csdn.net/learningstone/article/details/7932363

http://hi.baidu.com/sdink/item/85fa00d09864e01ed90e449a

  • 3
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
### 回答1: Qt 为我们提供了一种简单的方法,可以在应用程序启动时将其最小化到系统托盘。 首先,我们需要在项目包含 `<QSystemTrayIcon>` 头文件。接下来,在创建 `QApplication` 实例之前,我们可以设置一个标志位以指示应用程序将被最小化托盘。 例如,我们可以在 `main.cpp` 文件添加以下代码: ```c++ #include <QApplication> #include <QSystemTrayIcon> int main(int argc, char *argv[]) { QApplication a(argc, argv); // 设置标志位以指示应用程序将被最小化托盘 bool startMinimizedToTray = true; // 创建托盘图标 QSystemTrayIcon *trayIcon = new QSystemTrayIcon(QIcon("icon.png")); // 将应用程序最小化到系统托盘 if (startMinimizedToTray) { a.setWindowIcon(QIcon("icon.png")); trayIcon->show(); } // 其他应用程序逻辑 return a.exec(); } ``` 在上述代码,我们首先设置了一个 `startMinimizedToTray` 标志位,用于指示应用程序是否将被最小化托盘。然后,我们创建了一个 `QSystemTrayIcon` 对象并设置了一个应用程序图标(在此例,我们假设有一个名为 "icon.png" 的图标文件)。最后,如果 `startMinimizedToTray` 标志位为真,则将应用程序的图标显示在系统托盘。 这样,当我们运行应用程序时,它将首先在系统托盘显示图标,而不是在任务栏。用户可以通过单击托盘图标来恢复应用程序的正常窗口。 ### 回答2: Qt是一个跨平台的应用程序框架,可以用于开发图形用户界面(GUI)程序。启动最小化托盘是一种常见的功能,允许程序在启动时最小化到任务栏的系统托盘区域。 要实现这个功能,首先需要引入QSystemTrayIcon类,这个类提供了操作系统托盘的接口。然后在程序的主窗口创建一个QSystemTrayIcon对象。 接下来,可以使用hide()函数将主窗口隐藏,并使用showMinimized()函数将窗口最小化。然后,调用setContextMenu()函数,为托盘图标设置一个菜单,可以在用户右键单击托盘图标时显示。菜单可以包含恢复窗口、退出程序等选项。 在程序的槽函数,可以监听相关的事件,如托盘图标被双击、菜单项被点击等。当用户双击托盘图标时,可以调用showNormal()函数将窗口恢复正常显示。当用户选择退出程序时,可以调用QApplication的quit()函数退出程序。其他的一些槽函数可以根据需要来定义。 最后,在程序的main函数实例化QApplication对象,并将程序的主窗口作为参数传递给QSystemTrayIcon的构造函数。然后,调用show()函数显示主窗口。 通过以上的步骤,程序在启动时会先最小化到系统托盘区域,用户可以通过托盘图标进行操作。这样做的好处是不会占用用户的任务栏空间,而且用户可以随时将窗口恢复显示,方便快捷。 ### 回答3: 要在Qt实现将应用程序启动最小化到系统托盘,可以按照以下步骤进行操作: 1. 首先,需要在应用程序添加`QSystemTrayIcon`类的实例,该类提供了访问系统托盘图标的功能。可以在应用程序的主窗口添加一个成员变量来保存`QSystemTrayIcon`对象。 2. 创建一个菜单,用于点击托盘图标时显示的菜单项。可以使用`QMenu`和`QAction`类来创建并添加菜单项。 3. 接下来,在应用程序的`main()`函数,需要检查当前操作系统是否支持系统托盘功能。如果不支持,则不进行后续操作。 4. 当应用程序窗口关闭时,需要将其最小化到系统托盘。可以通过重写应用程序类的`closeEvent()`函数来实现。在该函数,需要将主窗口隐藏,并设置`QSystemTrayIcon`对象的图标和菜单。 5. 最后,在`QSystemTrayIcon`的槽函数处理托盘图标的点击事件。可以根据具体需求来实现不同的功能,比如恢复应用程序窗口、退出应用程序等。 需要注意的是,启动最小化到系统托盘功能在不同平台上的实现方式可能有所不同。因此,在进行具体实现时,需要根据目标平台和Qt版本选择适当的方法和事件。 以上是实现在Qt将应用程序启动最小化到系统托盘的一般步骤。具体的实现方式还需要根据应用程序的具体需求和平台特性进行调整。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值