QT实现托盘图标,弹出气泡消息(类似微信托盘)

本文介绍QT托盘图标和气泡消息的实现.效果图如下:

本文参考的例子是SystemTray.7z,已经上传gitee,从版权申请来看,这个例子是QT官方的例子,我觉得写得特别好.
原例子的所有UI都是动态创建的, 我修改成用QT设计器生成UI,这样做的好处是能够减少代码量,让初学者更容易看懂.

//  
//1.QT托盘图标
//

a)创建托盘
QT托盘图标的主要的类是QSystemTrayIcon,创建的代码如下:

void MainWindow::createTrayIcon()
{
    //菜单项--打开主面板
    QAction* openMainPanel = new QAction("打开主面板", this);
    connect(openMainPanel, SIGNAL(triggered()), this, SLOT(showMainPanel()));

    //菜单项--退出
    QAction* quitAction = new QAction("退出", this);
    connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));

    //菜单
    QMenu* trayIconMenu = new QMenu(this);
    trayIconMenu->addAction(openMainPanel);
    trayIconMenu->addSeparator();
    trayIconMenu->addAction(quitAction);

    //创建系统托盘图标
    m_trayIcon = new QSystemTrayIcon(this);
    //设置托盘图标的右键菜单
    m_trayIcon->setContextMenu(trayIconMenu);
}

上面的代码不光创建了系统托盘图标 QSystemTrayIcon 还创建了一个右键菜单,
这样,右键点托盘图标,就会出现菜单了.

b)设置托盘的图标

void MainWindow::setIcon(int index)
{
    //从ComboBox里取出图标
    QIcon icon = ui->iconComboBox->itemIcon(index);
    //设置托盘的图标
    m_trayIcon->setIcon(icon);
    //设置主窗口的图标
    setWindowIcon(icon);

    //当鼠标悬停在托盘图标上,显示的消息
    m_trayIcon->setToolTip(ui->iconComboBox->itemText(index));
}

m_trayIcon->setIcon(icon);这行代码是用来设置托盘的图标的.
m_trayIcon->setToolTip(ui->iconComboBox->itemText(index)); 这行代码是用来设置"当鼠标悬停在托盘图标上,显示的消息"


c)设置托盘的事件处理
1.右键点击弹出菜单: m_trayIcon->setContextMenu(trayIconMenu);
2.用户点击弹出的消息
    connect(m_trayIcon, SIGNAL(messageClicked()), this, SLOT(messageClicked()));

3.用户左键点击图标/双击图标/鼠标中键点击图标
    connect(m_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
            this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

处理函数如下:

void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason) {
    case QSystemTrayIcon::Trigger: //鼠标左键点击图标
    {
        showMainPanel();
        break;
    }
    case QSystemTrayIcon::DoubleClick: //鼠标左键双击图标
        ui->iconComboBox->setCurrentIndex((ui->iconComboBox->currentIndex() + 1)
                                      % ui->iconComboBox->count());
        break;
    case QSystemTrayIcon::MiddleClick: //鼠标中键点击图标
        on_showMessageButton_clicked();
        break;
    default:
        ;
    }
}

另外,补充一下,显示和隐藏托盘图标的代码是:m_trayIcon->setVisible(true/false)


//  
//2.QT右下角弹出消息
//


在右下角图标显示的情况下,调用showMessage来显示
void QSystemTrayIcon::showMessage(
const QString &title,
const QString &message,
QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information,
int millisecondsTimeoutHint = 10000)

实现代码如下:

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

//   
//3.关闭主窗口,不退出
//   

继承虚函数closeEvent,并忽略这个消息

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (m_trayIcon->isVisible())
    {
        hide(); //隐藏主窗口
        event->ignore(); //忽略这个消息
    }
}

//   
//4.点击菜单"打开主面板"显示主窗口
//   


connect(openMainPanel, SIGNAL(triggered()), this, SLOT(showMainPanel())); //连接处理函数

void MainWindow::showMainPanel()
{
    showNormal();
    activateWindow();
    setWindowState((windowState() & ~Qt::WindowMinimized) | Qt::WindowActive);
    raise();//必须加,不然X11会不起作用
}

参考https://zhuanlan.zhihu.com/p/161299504
关于win10的部分我没有测试.

 

[问题]
还记得m_trayIcon->setToolTip吗,这个可以设置鼠标悬停后,产生一个提示文字,比如"网易邮箱大师"效果如下:

可是,我自己写的程序,鼠标悬停后,却没有显示任何消息.如果有人知道原因,请告知.

代码见:http://q1024.com/files/qt_window-master.zip  000500目录

posted @ 2022-09-08 08:44  xingzaicpp  阅读(1287)  评论(1编辑  收藏  举报