天天看点

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

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

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

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

最基本的思路是拦截窗口的最小化事件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();  

}

}  

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

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

贴出效果图:

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

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

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

[cpp]  view plain copy print ?

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

继续阅读