理论摘自网友:https://blog.csdn.net/zhuyunfei/article/details/51433822
1.功能说明
对于GUI程序,如果想要实现当最小化时,程序从任务栏消失,在系统托盘显示一个图标,表示此程序,并能在托盘内通过双击或者菜单使程序界面恢复。
2.使用的类
主要使用的此类:QSystemTrayIcon。
其中QSystemTrayIcon是主要操作系统托盘的操作类,通过此类,可以在托盘显示指定程序的图标,响应用户鼠标的单击,双击,或wheel操作(好像只对X11系统有用),显示指定消息,显示菜单等。
此类中有两个枚举类型,分别如下:
enum QSystemTrayIcon::ActivationReason 表述托盘上图标的触发缘由
常量 | 值 | 描述 |
QSystemTrayIcon::Unknown | 0 | 未知原因 |
QSystemTrayIcon::Context | 1 | 请求系统托盘的上下文菜单 |
QSystemTrayIcon::DoubleClick | 2 | 鼠标双击 |
QSystemTrayIcon::Trigger | 3 | 鼠标单击 |
QSystemTrayIcon::MiddleClick | 4 | 鼠标中间按键 |
enum QSystemTrayIcon::MessageIcon 当显示气球消息时显示的图片
常量 | 值 | 描述 |
QSystemTrayIcon::NoIcon | 0 | 不显示图标 |
QSystemTrayIcon::Information | 1 | 显示信息图标 |
QSystemTrayIcon::Warning | 2 | 显示告警图标 |
QSystemTrayIcon::Critical | 3 | 显示致命图标 |
3.QSystemTrayIcon常用函数
void setIcon(const QIcon& icon)
设置系统托盘的图标
void setToolTip(const QString &tip)
设置鼠标放到图标上的提示文字
void setContextMenu(QMenu* menu);
设置当点击图标弹出的菜单
void show()
显示系统托盘图标
4、实现步骤:
1)添加成员变量:
QSystemTrayIcon m_systray;
2)构造函数里面初始化:1、提示文字 2、设置图标 3、右键菜单 4、show显示
// 设置提示文字
m_systray.setToolTip(GBK::ToUnicode("JTV手动改名工具..."));
// 设置托盘图标
m_systray.setIcon(QIcon(":/JTVManualRename/Resources/Rename.ico"));
// 设置托盘菜单
QMenu* menu = new QMenu();
menu->addAction(ui.actionExit);
m_systray.setContextMenu(menu);
// 显示托盘菜单
m_systray.show();
3)为右键退出菜单添加一个槽函数:
// 托盘菜单命令的处理
connect(ui.actionExit,SIGNAL(triggered()),this,SLOT(OnExit()));
/*
托盘退出命令
*/
int CZZCMainFrame::OnExit()
{
QApplication::exit(0);
return 0;
}
4)点击图标时,显示主窗口:(关联托盘事件)
// 关联托盘事件
connect(&m_systray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
this,SLOT(OnSystemTrayClicked(QSystemTrayIcon::ActivationReason)));
/*
单击/双击托盘图标,显示主程序
*/
int CZZCMainFrame::OnSystemTrayClicked(QSystemTrayIcon::ActivationReason reason)
{
if(reason == QSystemTrayIcon::Trigger
|| reason == QSystemTrayIcon::DoubleClick)
{
// 显示主窗口
this->showNormal();
//this->showMaximized();
}
return 0;
}
5)点击最小化按钮时,加入系统托盘:(重写ChangeEvent事件)
/*
点击最小化时图标到托盘
*/
void CZZCMainFrame::changeEvent(QEvent* event)
{
if(event->type() == QEvent::WindowStateChange){
if(windowState() & Qt::WindowMinimized){
QTimer::singleShot(0, this, SLOT(hide()));
m_systray.show();
}
QWidget::changeEvent(event);
}
}
6)点击红X时,弹出选择对话框,最小化托盘或是退出主程序:(重写CloseEvent事件)
/*点击红X,最小到托盘*/
void CZZCMainFrame::closeEvent(QCloseEvent *event)
{
//如果不设置父窗口会出现两个图标
CloseInfoDlg dlg(this);
if (dlg.exec() == QDialog::Accepted)
{
if (dlg.m_nCFlag == 1)
{
this->hide();
event->ignore();
}
else
{
event->accept();
}
}
else
{
event->ignore();
}
}
同时添加一个对话框类:
#ifndef CLOSEINFODLG_H
#define CLOSEINFODLG_H
#include <QDialog>
#include "ui_CloseInfoDlg.h"
#include <QButtonGroup>
#include <QDebug>
class CloseInfoDlg : public QDialog
{
Q_OBJECT
public:
CloseInfoDlg(QWidget *parent = 0);
~CloseInfoDlg();
private:
Ui::CloseInfoDlg ui;
QButtonGroup *btnGroup;
public:
int m_nCFlag;
private slots:
void OnRadioClicked();
};
#endif // CLOSEINFODLG_H
#include "CloseInfoDlg.h"
CloseInfoDlg::CloseInfoDlg(QWidget *parent)
: QDialog(parent)
{
ui.setupUi(this);
setWindowTitle(QString::fromLocal8Bit("关闭窗口"));
m_nCFlag = 1;
btnGroup = new QButtonGroup(this);
btnGroup->addButton(ui.radiosystray,0);
btnGroup->addButton(ui.radioexit,1);
ui.radiosystray->setChecked(true);
/*
多个radio共享一个槽函数
*/
connect(ui.radiosystray,SIGNAL(clicked()),this,SLOT(OnRadioClicked()));
connect(ui.radioexit,SIGNAL(clicked()),this,SLOT(OnRadioClicked()));
connect(ui.btnOk,SIGNAL(clicked()),this,SLOT(accept()));
connect(ui.btnCancel,SIGNAL(clicked()),this,SLOT(reject()));
}
CloseInfoDlg::~CloseInfoDlg()
{
}
void CloseInfoDlg::OnRadioClicked()
{
switch (btnGroup->checkedId())
{
case 0:
m_nCFlag = 1;
break;
case 1:
m_nCFlag = 2;
break;
default:
break;
}
}