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界面设置
运行结果:
托盘菜单
注意:
- 要做闪烁操作时,需要更新图标,且我在测试时,更新的图标路径不能为空,否则没有闪烁效果。
- 要显示托盘图标需要主动调用托盘图标的show函数。
- 当笔记本通知无效时考虑是设置问题,打开下图选项即可。