我是QT新手,遇到了问题。
我决定尝试使用Qt和QSystemTrayIcon编写一个小型应用程序。首先,我决定从Qt的官方网站复制该示例。
https://doc.qt.io/qt-5/qtwidgets-desktop-systray-example.html?
这是我的头文件:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSystemTrayIcon>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QMenu *trayIconMenu;
QAction *launchAction;
QAction *quitAction;
QSystemTrayIcon *trayIcon;
public slots:
void changeEvent(QEvent*);
void trayIconActivated(QSystemTrayIcon::ActivationReason reason);
void trayActionExecute();
void setTrayIconActions();
void showTrayIcon();
};
#endif // MAINWINDOW_H
这是我的源代码文件:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
this->setTrayIconActions();
this->showTrayIcon();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::showTrayIcon() {
trayIcon = new QSystemTrayIcon(this);
QIcon trayImage(":/images/trayIcon.png");
trayIcon->setIcon(trayImage);
trayIcon->setContextMenu(trayIconMenu);
connect(trayIcon,
SLOT(activated(QSystemTrayIcon::ActivationReason)),
this,
SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason)));
trayIcon->show();
}
void MainWindow::trayActionExecute() {
QMessageBox::information(this, "TrayIcon", "Info text");
}
void MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason
reason) {
switch (reason) {
case QSystemTrayIcon::Trigger:
case QSystemTrayIcon::DoubleClick:
this->trayActionExecute();
break;
default:
break;
}
}
void MainWindow::showMsg() {
QMessageBox::information(this, "Tray message", "Hello world!");
}
void MainWindow::setTrayIconActions() {
launchAction = new QAction("Launch", this);
quitAction = new QAction("Exit", this);
connect (launchAction, SIGNAL(triggered()), this, SLOT(showMsg()));
connect (quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
// Setting system tray's icon menu
trayIconMenu = new QMenu(this);
trayIconMenu -> addAction (launchAction);
trayIconMenu -> addAction (quitAction);
}
void MainWindow::changeEvent(QEvent *event) {
QMainWindow::changeEvent(event);
if (event->type() == QEvent::WindowStateChange) {
if (isMinimized()) {
this->hide();
}
}
}
当我在上下文菜单中执行任何操作时,该应用程序仅关闭。我认为关键是要重写方法QCloseEvent,这将解决这种情况。所以,我重新实现它:
void MainWindow::closeEvent(QCloseEvent *event) {
#ifdef Q_OS_OSX
if (!event->spontaneous() || !isVisible()) {
return;
}
#endif
if (trayIcon->isVisible()) {
QMessageBox::information(this, tr("Systray"),
tr("The program will keep running in the "
"system tray"));
hide();
event->ignore();
}
}
有什么事吗
谢谢。
可以通过最小化主窗口(根据您的changeEvent()
实现将其隐藏),然后单击系统任务栏图标菜单中的“启动”来重现该问题。显示消息框,然后关闭应用程序。
这是由QT的“功能” QuitOnLastWindowClosed
(默认情况下启用)引起的。如果启用了该功能,则在关闭最后一个非隐藏窗口时,应用程序将退出-在您的示例中,这是“启动”命令(视为窗口)产生的消息框!
您可以通过QApplication::setQuitOnLastWindowClosed(false);
在创建之后的某个时间调用来解决此问题QApplication
,例如,main.cpp
其中可能会设置您的应用程序:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
a.setQuitOnLastWindowClosed(false);
MainWindow w;
w.show();
return a.exec();
}
另外,您输入的connect()
语法showTrayIcon()
有误:应该拼写SIGNAL(activated(QSystemTrayIcon::ActivationReason))
而不是SLOT(activated(QSystemTrayIcon::ActivationReason))
。
但我强烈建议您使用新的信号/插槽语法(https://wiki.qt.io/New_Signal_Slot_Syntax)代替:
connect(trayIcon, &QSystemTrayIcon::activated, this, &MainWindow::trayIconActivated);
这样的好处是可以在编译时而不是运行时向您显示任何错误(例如未知信号/插槽或不兼容的参数)。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句