背景:项目需要win环境下的exe最小化到托盘,点击时恢复,彻底关闭时需要通过对托盘中的图片右键点击。
Qt的官方例子有一个最小化托盘的小程序,实现了图标变换等操作,此程序参照了官方示例,更改了一些设计。
main.cpp
- 创建了一个普通窗口,在主程序开始初始化图片资源文件,Q_INIT_RESOURCE(test)中的test即为资源配置文件名,我的为test.qrc。
- isSystemTrayAvailable()是QSystemTrayIcon类中的静态函数,左右是检查当前系统的托盘是否可用,可以返回true,否则返回false。
#include "mainwindow.h"
#include <QMessageBox>
#include <QApplication>
#include <QSystemTrayIcon>
int main(int argc, char *argv[])
{
Q_INIT_RESOURCE(test);
QApplication a(argc, argv);
if(!QSystemTrayIcon::isSystemTrayAvailable()){
QMessageBox::critical(0,QObject::tr("Systray"),
QObject::tr("I couldn't detect any system tray "
"on this system."));
return 1;
}
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
- 要显示的窗口进行扩写,Qt官方例子使用的Dailog,本文使用的是mainwindow,大同小异,目标都是界面的最小化,都可以实现。
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSystemTrayIcon>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
class QAction;
class QCheckBox;
class QComboBox;
class QGroupBox;
class QMenu;
class QPushButton;
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
int OnSystemTrayClicked(QSystemTrayIcon::ActivationReason reason);
private:
Ui::MainWindow *ui;
QSystemTrayIcon *m_systray;
QCheckBox *showIconCheckBox;
QComboBox *typeComboBox;
QPushButton *showMessageButton;
QAction *minimizeAction;
QAction *maximizeAction;
QAction *restoreAction;
QAction *quitAction;
QMenu *trayIconMenu;
void createAction();
void createCloseMenu();
void closeEvent(QCloseEvent *event) override;
};
#endif // MAINWINDOW_H
mainwindow.cpp
- 构造函数中实例化一个QSystemTrayIcon类。
- 使用方法setToolTip设置最小化后图片的名字。
- 方法setIcon设置最小化后的图片,如果不设置则是空白的方框。
- OnSystemTrayClicked是实现左键点击托盘图标,使应用程序恢复到正常的状态。
- createAction()则是创建一些右键点击的动作。
- createCloseMenu把右键点击动作添加到一个菜单栏中显示出来。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QCoreApplication>
#include <QCloseEvent>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_systray = new QSystemTrayIcon(this);
m_systray->setToolTip("CTest");
m_systray->setIcon(QIcon(":/new/images/dddd.png"));
connect(m_systray, &QSystemTrayIcon::activated,
this,&MainWindow::OnSystemTrayClicked);
m_systray->show();
createAction();
createCloseMenu();
}
MainWindow::~MainWindow()
{
delete ui;
}
int MainWindow::OnSystemTrayClicked(QSystemTrayIcon::ActivationReason reason)
{
if(reason == QSystemTrayIcon::Trigger || reason == QSystemTrayIcon::DoubleClick){
this->showNormal();
}
return 0;
}
void MainWindow::closeEvent(QCloseEvent *event)
{
if(m_systray->isVisible()){
this->hide();
event->ignore();
}
}
void MainWindow::createAction()
{
minimizeAction = new QAction(tr("最小化"), this);
connect(minimizeAction, &QAction::triggered, this, &QWidget::hide);
maximizeAction = new QAction(tr("最大化"), this);
connect(maximizeAction, &QAction::triggered, this, &QWidget::showMaximized);
restoreAction = new QAction(tr("恢复"), this);
connect(restoreAction, &QAction::triggered, this, &QWidget::showNormal);
quitAction = new QAction(tr("退出"), this);
connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit);
}
void MainWindow::createCloseMenu()
{
trayIconMenu = new QMenu(this);
trayIconMenu->addAction(minimizeAction);
trayIconMenu->addAction(maximizeAction);
trayIconMenu->addAction(restoreAction);
trayIconMenu->addSeparator();
trayIconMenu->addAction(quitAction);
m_systray->setContextMenu(trayIconMenu);
}