在菜单中执行任何操作后,Qt Tray应用程序将自行关闭

未知英雄123

我是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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

C# 控制台应用程序在我运行后自行关闭

应用程序可以在Windows中自行推送吗?

Facebook Leadgen 应用程序自行关闭

WebBrowser打印后关闭应用程序

关闭应用程序后如何调试

定位后应用程序突然关闭

关闭应用程序后每 24 小时执行一次操作 Unity

我的应用程序关闭后执行RxAndroid Observables

在Android应用程序中关闭ByteArrayOutputStream

如何从通知中关闭应用程序

在Android应用程序中关闭活动

关闭QT应用程序时如何关闭GLFW窗口

Qtwebengineprocess在应用程序关闭后未关闭

Onbackpressed关闭应用程序,登录后未关闭应用程序

在WPF中关闭事件后保持应用程序运行

关闭应用程序后,hashmap 中的数据不保存

关闭应用程序后如何在Android通知中显示操作按钮?

class-validator在NestJS应用程序中似乎没有执行任何操作

在Xcode中完全关闭应用程序后如何保留应用程序的内存

使用 app.relaunch 后,如何阻止 Electron 应用程序自行重启?

应用程序自行终止后,是否重新启动了START_STICKY服务?

在屏幕关闭时执行操作,但在应用程序进入后台时关闭

Azure中的Node.js + Express应用程序遇到500个可自行修复的错误

通过执行的应用程序关闭执行者应用程序

如何通过活动的Android应用程序菜单处理关闭python kivy应用程序

从主菜单返回时如何关闭应用程序

是否有应用程序在某个操作后关闭程序?

关闭应用程序时执行待写

Spring-在应用程序关闭之前执行查询(测试)