是否可以在 Qt Quick 应用程序中实现 SystemTrayIcon 功能

Posted

技术标签:

【中文标题】是否可以在 Qt Quick 应用程序中实现 SystemTrayIcon 功能【英文标题】:Is it possible to implement SystemTrayIcon functionality in Qt Quick application 【发布时间】:2014-06-26 06:03:43 【问题描述】:

我正在编写一个 QtQuick 桌面应用程序。我在其中同时使用 c++(用于功能)和 QML(用于 UI)。 我使用 QQuickView 来显示用 QML 编写的界面。

我希望此应用程序在最小化时驻留在系统托盘中。

我的意思是类似于此示例的功能。 http://qt-project.org/doc/qt-4.8/desktop-systray.html 。 我正在尝试实现此功能,但在我的 Qt Quick 应用程序中找不到实现此功能的方法。

这是我的 main.cpp 代码:

#include <QGuiApplication>
#include <QQmlEngine>
#include <QQmlContext>
#include <QQmlFileSelector>
#include <QQuickView>
#include "myapp.h"

int main(int argc, char* argv[])

    QGuiApplication app(argc,argv);
    app.setApplicationName(QFileInfo(app.applicationFilePath()).baseName());
    QDir::setCurrent(qApp->applicationDirPath());

    MyApp myappObject;

    QQuickView view;

    view.connect(view.engine(), SIGNAL(quit()), &app, SLOT(quit()));
    view.rootContext()->setContextProperty("myappObject", &myappObject);
    new QQmlFileSelector(view.engine(), &view);

    view.setSource(QUrl("qrc:///myapp.qml"));

    view.setResizeMode(QQuickView::SizeRootObjectToView);   
    view.show();

    return app.exec();

请提供任何提示/指针来帮助您执行此操作。

谢谢。

【问题讨论】:

你是想只用 QML 做这个,还是可以用 C++/Qt? 您好 BlueMagma,可以使用 C++/Qt。我的 UI 是使用 QML 创建的,我从 Qt main.cpp 文件启动它。我刚刚更新了我的问题中的 main.cpp 文件代码。 【参考方案1】:

我今天面临同样的挑战,最终在 main() 中使用了以下解决方案。使用 Qt 5.3 时对我很有用。您当然应该实现一种更好的方法来检查第一个根对象是否是您的应用程序窗口对象。

#include <QApplication>
#include <QQmlApplicationEngine>
#include <QMessageBox>
#include <QAction>
#include <QMenu>
#include <QSystemTrayIcon>

int main(int argc, char *argv[])

    QApplication app(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;
    
    QApplication::setQuitOnLastWindowClosed(false);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:///main.qml")));

    QObject *root = 0;
    if (engine.rootObjects().size() > 0)
    
        root = engine.rootObjects().at(0);

        QAction *minimizeAction = new QAction(QObject::tr("Mi&nimize"), root);
        root->connect(minimizeAction, SIGNAL(triggered()), root, SLOT(hide()));
        QAction *maximizeAction = new QAction(QObject::tr("Ma&ximize"), root);
        root->connect(maximizeAction, SIGNAL(triggered()), root, SLOT(showMaximized()));
        QAction *restoreAction = new QAction(QObject::tr("&Restore"), root);
        root->connect(restoreAction, SIGNAL(triggered()), root, SLOT(showNormal()));
        QAction *quitAction = new QAction(QObject::tr("&Quit"), root);
        root->connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));

        QMenu *trayIconMenu = new QMenu();
        trayIconMenu->addAction(minimizeAction);
        trayIconMenu->addAction(maximizeAction);
        trayIconMenu->addAction(restoreAction);
        trayIconMenu->addSeparator();
        trayIconMenu->addAction(quitAction);

        QSystemTrayIcon *trayIcon = new QSystemTrayIcon(root);
        trayIcon->setContextMenu(trayIconMenu);
        trayIcon->setIcon(QIcon(":/resources/DatagnanLogoColor.png"));
        trayIcon->show();
    

    return app.exec();

【讨论】:

缺点:它会导致 Qt5Widgets 模块依赖。似乎无法从普通 qml 使用系统托盘。【参考方案2】:

将 Windows 类 (window.cpp/window.h) 从 systray 示例复制到您的项目,如有必要将其移植到 Qt5 并从您的主文件中打开它们:

int main(int argc, char* argv[])

    // ...
    QQuickView view;
    // ... 
    view.show();

    Window window;
    window.show();

    return app.exec();

【讨论】:

嗨,Sion Wart,我在哪里可以获取 window.cpp 和 window.h 文件? 我明白你的意思是来自系统托盘示例的 windows.cpp /windows.h 文件。我尝试了它们并使它起作用。但是两个 Windows(一个源自 Window.cpp 和由 QML(通过 QQuickView)创建的基于 qml 的窗口)都出现了。它不能解决我的要求。如何集成它们。如果可能,请提供更多详细信息。 您现在需要在 C++ 中集成您的功能。根据您的需要修改Window 类,并开始在您的主程序和Window 之间发送信号,例如显示/隐藏/修改图标。

以上是关于是否可以在 Qt Quick 应用程序中实现 SystemTrayIcon 功能的主要内容,如果未能解决你的问题,请参考以下文章

如何在Python和Qt Quick QML应用程序中实现简化的双向数据绑定

新的拖放机制在 Qt-Quick (Qt 5.3) 中无法按预期工作

Quick-Cocos2d3.2RC1在Code IDE中实现代码提示

如何在 Qt 程序中实现 IDv3 标签? [关闭]

如何在 Qt 中实现基于 GStreamer 的视频小部件?

如何在Qt中实现QHoverEvent?