一、描述
为避免错点关闭按钮,使得软件关闭退出。需要开发一种类似于QQ桌面之类的功能,点击关闭按钮并不退出,开发的应用程序在用户鼠标点击右上角的关闭按钮时,程序不退出,缩小到右下角,进入托盘。例如win10右下角的图标。
二、思路
1、需要对应用软件程序窗口的关闭按钮进行事件拦截,然后重载,用到QT的QDesktopServices类。
2、要使程序进入托盘,需要用到QT的QSystemTrayIcon类。
三、方法
1、添加头文件和成员
mainwindow.h 头文件中添加:
#include <QSystemTrayIcon> //t托盘类
#include <QDesktopServices> //桌面事件类
private:
QMenu *trayMenu;//托盘菜单
QSystemTrayIcon *tray;//托盘图标添加成员
2、构造函数初始化
//***托盘***
tray= new QSystemTrayIcon(this);//初始化托盘对象tray
tray->setIcon(QIcon(QPixmap(":/image/image/icon_48px.png")));//设定托盘图标,引号内是自定义的png图片路径
tray->setToolTip("My helper"); //提示文字
QString title="APP Message";
QString text="My helper start up";
tray->show();//让托盘图标显示在系统托盘上
tray->showMessage(title,text,QSystemTrayIcon::Information,3000); //最后一个参数为提示时长,默认10000,即10s
//创建菜单项动作
minimizeAction = new QAction("MinWin", this);
connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));
maximizeAction = new QAction("MaxWin", this);
connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()))
restoreAction = new QAction("restore", this);
connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));
quitAction = new QAction("exit", this);
connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); //关闭应用
//创建托盘菜单
trayMenu = new QMenu(this);
trayMenu->addAction(minimizeAction);
trayMenu->addAction(maximizeAction);
trayMenu->addAction(restoreAction);
trayMenu->addSeparator();
trayMenu->addAction(quitAction);
tray->setContextMenu(trayMenu);
connect(tray,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
3、添加槽函数
void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason ireason)
{
switch (ireason)
{
case QSystemTrayIcon::Trigger:
this->showNormal();
break;
case QSystemTrayIcon::DoubleClick:
this->showNormal();
break;
case QSystemTrayIcon::MiddleClick:
break;
default:
break;
}
}
4、拦截桌面窗口事件
void MainWindow::closeEvent(QCloseEvent *event)
{
if(tray->isVisible())
{
hide(); //隐藏窗口
event->ignore(); //忽略事件
}
}
void MainWindow::hideEvent(QHideEvent *event)
{
if(tray->isVisible())
{
hide(); //隐藏窗口
event->ignore(); //忽略事件
}
}