Qt - 系统托盘(QSystemTrayIcon)

mainwindow.h

#ifndef CMAINWINDOW_H
#define CMAINWINDOW_H

#include <QTimer>
#include <QMainWindow>
#include <QSystemTrayIcon>
#include <QAbstractButton>

QT_BEGIN_NAMESPACE
namespace Ui { class CMainWindow; }
QT_END_NAMESPACE

class CMainWindow : public QMainWindow
{
    Q_OBJECT

public:
    CMainWindow(QWidget *parent = nullptr);
    ~CMainWindow();

    void createActions();
    void createMenu();

private slots:
    /*
     on_systemTrayActivated 托盘图标响应槽函数
     reason 响应操作(支持单击,双击,右键,滚轮按下等)
     */
    void on_systemTrayActivated(QSystemTrayIcon::ActivationReason reason);

    /*
      on_btnGroup_buttonClicked 按钮组点击槽函数
      btn 点击的按钮
     */
    void on_btnGroup_buttonClicked(QAbstractButton *btn);

    /*
       on_btnTwinkle_clicked 闪烁响应槽函数
     */
    void on_btnTwinkle_clicked();

    // QObject interface
    void on_btnNoIcon_clicked();

    void on_btnInfomation_clicked();

    void on_btnWarning_clicked();

    void on_btnCritical_clicked();

    void on_showMainAction();

    void on_exitAppAction();

protected:
    /*
      timerEvent 定时器事件
      event 定时器事件对象
     */
    void closeEvent(QCloseEvent *event);
    void timerEvent(QTimerEvent *event);

private:
    Ui::CMainWindow *ui;

    QSystemTrayIcon *m_sysTrayIcon; // 托盘图标对象

    int             m_iTimer;   // 定时器接收变量

    QAction* m_showMainAction;
    QAction* m_exitAppAction;
    QMenu *m_menu;
};
#endif // CMAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include <QCloseEvent>
#include <QDebug>

CMainWindow::CMainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::CMainWindow)
{
    ui->setupUi(this);

    // 创建托盘图标对象
    m_sysTrayIcon = new QSystemTrayIcon(this);
    // 设置托盘图标
    m_sysTrayIcon->setIcon(QIcon(":/image/C++.png"));
    // 设置悬浮提示文本
    m_sysTrayIcon->setToolTip(u8"托盘测试");
    // 显示托盘图标
    m_sysTrayIcon->show();

    createActions();
    createMenu();

    //链接最小化托盘类的点击事件信号
    connect(m_sysTrayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this, SLOT(on_systemTrayActivated(QSystemTrayIcon::ActivationReason)));
}

CMainWindow::~CMainWindow()
{
    // 释放指针对象
    delete m_sysTrayIcon;
    delete ui;
}

//创建动作
void CMainWindow::createActions()
{
    m_showMainAction = new QAction("打开主窗口", this);
    connect(m_showMainAction,SIGNAL(triggered()),this,SLOT(on_showMainAction()));

    m_exitAppAction = new QAction("退出", this);
    connect(m_exitAppAction,SIGNAL(triggered()),this,SLOT(on_exitAppAction()));
}

//创建托盘菜单
void CMainWindow::createMenu()
{
    m_menu = new QMenu(this);
    //新增菜单项---显示主界面
    m_menu->addAction(m_showMainAction);
    //增加分隔符
    m_menu->addSeparator();
    //新增菜单项---退出程序
    m_menu->addAction(m_exitAppAction);
    //把QMenu赋给QSystemTrayIcon对象
    //m_sysTrayIcon->setContextMenu(m_menu);使用此函数就可以不需要m_menu->exec()了
}


void CMainWindow::on_systemTrayActivated(QSystemTrayIcon::ActivationReason reason)
{
    // 根据reason对象响应对应操作
    // 需要对应的操作在对应模块中添加即可
    switch (reason)
    {
    case QSystemTrayIcon::Unknown:
    {
        ui->textBrowser->append(u8"未知原因");
        break;
    }
    case QSystemTrayIcon::Context:
    {
        ui->textBrowser->append(u8"上下文菜单");
        m_menu->exec(QCursor::pos());//QCursor::pos()确保右键菜单在当前鼠标坐标出现
        break;
    }
    case QSystemTrayIcon::DoubleClick:
    {
        //m_sysTrayIcon->hide();//隐藏托盘
        this->show();//显示主界面
        ui->textBrowser->append(u8"双击");
        break;
    }
    case QSystemTrayIcon::Trigger:
    {
        ui->textBrowser->append(u8"单击");
        break;
    }
    case QSystemTrayIcon::MiddleClick:
    {
        ui->textBrowser->append(u8"滚轮按下");
        break;
    }
    default:
        break;
    }
}

void CMainWindow::on_btnTwinkle_clicked()
{
    if(0 == ui->btnTwinkle->text().compare(u8"停止闪烁"))
    {
        // 杀死定时器
        killTimer(m_iTimer);
        // 更新按钮文本
        ui->btnTwinkle->setText(u8"开始闪烁");
        // 恢复托盘图标
        m_sysTrayIcon->setIcon(QIcon(":/setting.png"));
    }
    else
    {
        // 启动定时器
        m_iTimer = startTimer(500);
        // 更新按钮文本
        ui->btnTwinkle->setText(u8"停止闪烁");
    }
}

void CMainWindow::closeEvent(QCloseEvent *event)
{

    QMessageBox::information(this,"提示","程序最小化,通过系统托盘右键关闭");
    this->hide();   //隐藏主程序
    event->ignore();//忽略关闭事件,这样才不会关闭程序
}

void CMainWindow::timerEvent(QTimerEvent *event)
{
    // 定义标记变量
    static bool flag = false;
    //获取当前托盘图标字符串
    //此处 :/null.png 图片不存在,不过我自测的时候此处字符串不能为空
    QString iconStr = flag? ":/image/C++.png": ":/null.png";
    // 设置图标
    m_sysTrayIcon->setIcon(QIcon(iconStr));
    // 更新标记值
    flag = !flag;
}

//当在系统托盘点击菜单内的显示主界面操作
void CMainWindow::on_showMainAction()
{
    this->show();
}

//当在系统托盘点击菜单内的退出程序操作
void CMainWindow::on_exitAppAction()
{
    qApp->exit();
}

void CMainWindow::on_btnGroup_buttonClicked(QAbstractButton *btn)
{
    // 获取按钮文本
    QString text = btn->text();
    // 获取点击类型
    QSystemTrayIcon::MessageIcon msgIcon = static_cast<QSystemTrayIcon::MessageIcon>(btn->property("MessageIcon").toInt());
    // 显示点击按钮的对应信息
    m_sysTrayIcon->showMessage(text + u8"标题", text, msgIcon, 1000);
}

void CMainWindow::on_btnNoIcon_clicked()
{
    on_btnGroup_buttonClicked(ui->btnNoIcon);
}

void CMainWindow::on_btnInfomation_clicked()
{
    on_btnGroup_buttonClicked(ui->btnInfomation);
}

void CMainWindow::on_btnWarning_clicked()
{
    on_btnGroup_buttonClicked(ui->btnWarning);
}

void CMainWindow::on_btnCritical_clicked()
{
    on_btnGroup_buttonClicked(ui->btnCritical);
}

ui界面设置

 

运行结果:

托盘菜单

 

注意:

  1. 要做闪烁操作时,需要更新图标,且我在测试时,更新的图标路径不能为空,否则没有闪烁效果。
  2. 要显示托盘图标需要主动调用托盘图标的show函数。
  3. 当笔记本通知无效时考虑是设置问题,打开下图选项即可。

posted @ 2024-03-01 16:40  [BORUTO]  阅读(89)  评论(0编辑  收藏  举报