Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

    [SOLVED] How to use QPlatformSystemTrayIcon or QSystemTrayIcon with Qt Quick Application?

    QML and Qt Quick
    3
    17
    5302
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • Q
      qt_sur last edited by

      Hi,

      I'm quite new to how Qt QML (started learning Qt only from the QML days) works with Qt Gui or Widgets.
      I can't seem to include & compile QPlatformSystemTrayIcon: http://qt-project.org/doc/qt-5/qplatformsystemtrayicon.html

      That is, I add the "QT += gui" (along with others which are needed) and do "#include <QPlatformSystemTrayIcon>".
      The include statement is showing to be missing. Perhaps the documentation is just outdated in terms of what needs to be included?

      And I can't seem to have anything show up using QSystemTrayIcon (it compiles at least): http://qt-project.org/doc/qt-5/qsystemtrayicon.html
      But QSystemTrayIcon seems to be under "widgets".

      What I have is the default project setting that you get when you choose "Qt Quick Application", using Qt Creator. That is, my main.cpp has something like the following:

      @int main(int argc, char *argv[])
      {
      QGuiApplication app(argc, argv);
      // Some other qml register calls, to register custom qml types
      ///
      QtQuick2ApplicationViewer viewer;
      viewer.setMainQmlFile(QStringLiteral("qml/MyProject/main.qml"));

      return app.exec&#40;&#41;;
      

      }@

      The QtQuick2ApplicationViewer inherits QQuickView; qtquick2applicationviewer.h & qtquick2applicationviewer.cpp are the classes that the project creates automatically.

      Any help would be greatly appreciated.

      Thanks.

      1 Reply Last reply Reply Quote 0
      • dheerendra
        dheerendra Qt Champions 2022 last edited by

        What is the error you are facing ? Not able yo compile ?

        Dheerendra
        @Community Service
        Certified Qt Specialist
        http://www.pthinks.com

        1 Reply Last reply Reply Quote 0
        • Q
          qt_sur last edited by

          Hi again,

          For "#include <QPlatformSystemTrayIcon>" I just get the following:

          error: 'QPlatformSystemTrayIcon' file not found
          #include <QPlatformSystemTrayIcon>
          ^

          I have made sure that my Qt Creator's project is pointing to the right Qt folder. I also made sure that the following file exists:

          5.3/clang_64/lib/QtGui.framework/Versions/Current/Headers/5.3.1/QtGui/qpa/qplatformsystemtrayicon.h

          I also tried to see it works with "#include <QtGui/QPlatformSystemTrayIcon>" or "#include <QtGui/qpa/qplatformsystemtrayicon.h>". But nothing. I get the same type of error "..not found".

          Any help would be really appreciated.

          Thanks.

          1 Reply Last reply Reply Quote 0
          • dheerendra
            dheerendra Qt Champions 2022 last edited by

            Try adding something like this.

            @pro file
            INCLUDEPATH = <QtBaseDir>/Qt5.3.1/5.3/clang_64/lib/QtGui.framework/Versions/5/Headers/5.3.1/QtGui/qpa

            #include <qplatformsystemtrayicon.h>@

            Dheerendra
            @Community Service
            Certified Qt Specialist
            http://www.pthinks.com

            1 Reply Last reply Reply Quote 0
            • Q
              qt_sur last edited by

              Thanks. I got the first class to compile now. But still not sure how to use. It seems that it is an abstract class; unlike QSystemTrayIcon class, which can be instantiated (but that uses "widgets" instead of the "gui".

              Do I need to implement my own class, inheriting from QPlatforSystemTrayIcon? If that's the case, how do I actually interact with the OS to show the notifications?

              Also, just a FYI, I actually had to do the following include to get this abstract class detected in compilation:

              @#include <qpa/qplatformsystemtrayicon.h>@

              And in the .pro file:

              @mac:INCLUDEPATH = $$(QTDIR)/lib/QtGui.framework/Versions/5/Headers/5.3.1/QtGui
              @

              Thanks again. Looking forward to see if anyone has any ideas on how to actually use this class.

              1 Reply Last reply Reply Quote 0
              • SGaist
                SGaist Lifetime Qt Champion last edited by

                Hi,

                QPlatformSystemTrayIcon is not what you want to use here. Just use QSystemTrayIcon. The former is to create the specialized version for your platform and is used indirectly by QSystemTrayIcon.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply Reply Quote 0
                • Q
                  qt_sur last edited by

                  Hi all,

                  Unfortunately, that is one of the main issues I have been facing, since the beginning of this thread: not sure how to exactly use "widgets" in a Qt Quick Application (which is using QML and CPP back and forth).

                  I have tried initializing QSystemTrayIcon right before "return app.exec()" in main.cpp.
                  I have also tried to do when a button gets invoked from the main.qml (Q_INVOKABLE function), in a different .cpp class. But I don't see any results.

                  Do I need to create some other window? Or some other class?

                  Thanks.

                  1 Reply Last reply Reply Quote 0
                  • SGaist
                    SGaist Lifetime Qt Champion last edited by

                    did you add

                    @QT += widgets@

                    in your pro file in the first place ?

                    You also need to use a QApplication rather than a QGuiApplication

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply Reply Quote 0
                    • Q
                      qt_sur last edited by

                      Thanks :) I just had to switch the QGuiApplication with QApplication in:

                      @QGuiApplication app(argc, argv);@

                      After that, I had to make sure that the icon was actually set for QSystemTrayIcon; otherwise, it doesn't seem to show any messages. Maybe that's a bug, since it is useful for a notification widget to show messages, without any icons set. Also had to make sure that the QSystemTrayIcon is created and stored on the heap, dynamically, instead of the stack memory.

                      Either way, I should be able to continue development now. Will close off the thread ASAP.

                      1 Reply Last reply Reply Quote 0
                      • SGaist
                        SGaist Lifetime Qt Champion last edited by

                        A QSystemTrayIcon without an icon doesn't really make sense does it ? :D

                        You shouldn't need to allocate it on the heap in order to work. That seem pretty strange.

                        Can you show the code where you use this class ?

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply Reply Quote 0
                        • Q
                          qt_sur last edited by

                          Well, I was initially trying to use QSystemTrayIcon just to show the pop up message on the top right (for Mac), that dismisses after a period. I was referring to that messaging part - it should be regardless of whether an icon is set. Either, I was mistaken; it does show up even if I don't set the icon (so ignore that last comment).

                          I'll post my update regarding the other things as soon I find more info. Thanks.

                          1 Reply Last reply Reply Quote 0
                          • Q
                            qt_sur last edited by

                            Hi again,

                            I'm still having issues actually having the system tray icon to show up on the top right on the desktop, on Mac. The message shows up. But not the actual tray, with the context menu. I tried to reproduce it on a separate Qt Quick Application so that I can post it here. Here are my 3 code files:

                            Also:

                            • Declaring and initializing it in main.cpp, on stack, doesn't show the message. I had to declare it dynamically, on a separate class and use a Q_INVOKABLE function to invoke the message function from the UI
                            • The message shown actually uses the application's ICON set, on a different project. But for some reason, on this test project, it doesn't (but when the app runs, this test app does use the right icon on the dock bar on the Mac)

                            Any help would be greatly appreciated. Thanks.

                            main.cpp

                            @//#include <QGuiApplication>
                            #include <QApplication>
                            #include <QQmlApplicationEngine>

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

                            #include <QQmlContext> // needed for setting context property

                            #include <QtQml/qqml.h>

                            #include "uiextension.h"

                            int main(int argc, char *argv[])
                            {
                            //QGuiApplication app(argc, argv);
                            QApplication app(argc, argv);

                            QQmlApplicationEngine engine;
                            
                            UIExtension uiExt;
                            engine.rootContext()->setContextProperty("_app", &uiExt);
                            
                            engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
                            
                            QSystemTrayIcon sysTrayIcon;
                            
                            if (!QSystemTrayIcon::isSystemTrayAvailable()) {
                                QMessageBox::warning(0, QObject::tr("Systray"),QObject::tr("System Tray NOT DETECTED on this system"));
                            }
                            sysTrayIcon.showMessage("Title here", "App starting"); // <-- This never shows
                            
                            return app.exec();
                            

                            }@


                            uiextension.h:

                            @#ifndef UIEXTENSION_H
                            #define UIEXTENSION_H

                            #include <QObject>
                            #include <QSystemTrayIcon>
                            #include <QMenu>
                            #include <QAction>
                            #include <QDebug>

                            class UIExtension : public QObject
                            {
                            Q_OBJECT

                            public:

                            UIExtension(QObject *parent = 0);
                            ~UIExtension();
                            Q_INVOKABLE void showSystemTrayMessage(QString title, QString message);
                            

                            signals:

                            public slots:

                            private:

                            QSystemTrayIcon* _sysTrayIcon;
                            QMenu* _trayIconMenu;
                            
                            QAction *_minimizeAction;
                            QAction *_maximizeAction;
                            QAction *_restoreAction;
                            QAction *_quitAction;
                            

                            };

                            #endif // UIEXTENSION_H
                            @


                            uiextension.cpp

                            @#include "uiextension.h"
                            #include <QMessageBox>

                            UIExtension::UIExtension(QObject *parent) {

                            if (!QSystemTrayIcon::isSystemTrayAvailable()) {
                                QMessageBox::warning(0, QObject::tr("Systray"),QObject::tr("System Tray NOT DETECTED on this system"));
                                _sysTrayIcon = NULL;
                                _trayIconMenu = NULL;
                                _minimizeAction = NULL;
                                _maximizeAction = NULL;
                                _restoreAction = NULL;
                            
                            } else {
                                QIcon sysIconToSet("sysicon.png");  // Does this need to be exactly 22x22 on Mac?
                                _sysTrayIcon = new QSystemTrayIcon(this);
                                _sysTrayIcon->setIcon(sysIconToSet);
                                _sysTrayIcon->setVisible(true);
                            
                                _minimizeAction = new QAction("Minimize", this);
                                //connect(_minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));
                            
                                _maximizeAction = new QAction("Maximize", this);
                                //connect(_maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
                            
                                _restoreAction = new QAction("Restore", this);
                                //connect(_restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));
                            
                                _quitAction = new QAction("Quit", this);
                                //connect(_quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
                            
                                _trayIconMenu = new QMenu();
                                _trayIconMenu->addAction(_minimizeAction);
                                _trayIconMenu->addAction(_maximizeAction);
                                _trayIconMenu->addAction(_restoreAction);
                                _trayIconMenu->addSeparator();
                                _trayIconMenu->addAction(_quitAction);
                            
                                _sysTrayIcon->setContextMenu(_trayIconMenu);
                            
                                _sysTrayIcon->show();
                            }
                            

                            }

                            UIExtension::~UIExtension() {
                            if ( _sysTrayIcon != NULL ) delete _sysTrayIcon;
                            if ( _trayIconMenu != NULL ) delete _trayIconMenu;
                            if ( _minimizeAction != NULL ) delete _minimizeAction;
                            if ( _maximizeAction != NULL ) delete _maximizeAction;
                            if ( _restoreAction != NULL ) delete _restoreAction;
                            if ( _quitAction != NULL ) delete _quitAction;
                            }

                            void UIExtension::showSystemTrayMessage(QString title, QString message) {

                            if ( _sysTrayIcon != NULL ) {
                                _sysTrayIcon->showMessage(title, message);  // <--- This message shows up. But the app icon doesn't show on this project. However, the app icon showed on a different project
                            
                                QIcon iconSet = _sysTrayIcon->icon();
                                if ( iconSet.isNull()) {
                                    qDebug() << "ERROR : iconSet is NULL"; // this is not null
                                }
                            }
                            

                            }
                            @


                            main.qml

                            @import QtQuick 2.2
                            import QtQuick.Window 2.1
                            import QtQuick.Controls 1.2

                            Window {
                            visible: true
                            width: 360
                            height: 360

                            Rectangle {
                                anchors.fill: parent
                            
                                Button {
                                    text: "Sys Tray Message"
                                    onClicked: {
                                        _app.showSystemTrayMessage("Title From UI", "Message From UI");
                                        //_app.testPrint();
                                    }
                                }
                            }
                            

                            }@

                            1 Reply Last reply Reply Quote 0
                            • SGaist
                              SGaist Lifetime Qt Champion last edited by

                              @
                              sysTrayIcon.showMessage("Title here", "App starting"); // <-- This never shows
                              return app.exec();@

                              sysTrayIcon.showMessage might need running event loop and it's not been started yet

                              Interested in AI ? www.idiap.ch
                              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                              1 Reply Last reply Reply Quote 0
                              • Q
                                qt_sur last edited by

                                Yes, that's why I'm doing it later on, from uiextension.cpp Q_INVOKABLE. But I can't seem to get the system tray icon to show up on the top right of Mac.

                                @#include "uiextension.h"
                                #include <QMessageBox>

                                UIExtension::UIExtension(QObject *parent) {

                                if (!QSystemTrayIcon::isSystemTrayAvailable()) {
                                    QMessageBox::warning(0, QObject::tr("Systray"),QObject::tr("System Tray NOT DETECTED on this system"));
                                    _sysTrayIcon = NULL;
                                    _trayIconMenu = NULL;
                                    _minimizeAction = NULL;
                                    _maximizeAction = NULL;
                                    _restoreAction = NULL;
                                
                                } else {
                                    QIcon sysIconToSet("sysicon.png");  // Does this need to be exactly 22x22 on Mac?
                                    _sysTrayIcon = new QSystemTrayIcon(this);
                                    _sysTrayIcon->setIcon(sysIconToSet);
                                    _sysTrayIcon->setVisible(true);
                                
                                    _minimizeAction = new QAction("Minimize", this);
                                    //connect(_minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));
                                
                                    _maximizeAction = new QAction("Maximize", this);
                                    //connect(_maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized()));
                                
                                    _restoreAction = new QAction("Restore", this);
                                    //connect(_restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));
                                
                                    _quitAction = new QAction("Quit", this);
                                    //connect(_quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));
                                
                                    _trayIconMenu = new QMenu();
                                    _trayIconMenu->addAction(_minimizeAction);
                                    _trayIconMenu->addAction(_maximizeAction);
                                    _trayIconMenu->addAction(_restoreAction);
                                    _trayIconMenu->addSeparator();
                                    _trayIconMenu->addAction(_quitAction);
                                
                                    _sysTrayIcon->setContextMenu(_trayIconMenu);
                                
                                    _sysTrayIcon->show();
                                }
                                

                                }

                                UIExtension::~UIExtension() {
                                if ( _sysTrayIcon != NULL ) delete _sysTrayIcon;
                                if ( _trayIconMenu != NULL ) delete _trayIconMenu;
                                if ( _minimizeAction != NULL ) delete _minimizeAction;
                                if ( _maximizeAction != NULL ) delete _maximizeAction;
                                if ( _restoreAction != NULL ) delete _restoreAction;
                                if ( _quitAction != NULL ) delete _quitAction;
                                }

                                void UIExtension::showSystemTrayMessage(QString title, QString message) {

                                if ( _sysTrayIcon != NULL ) {
                                    _sysTrayIcon->showMessage(title, message);  // <--- This message shows up. But the app icon doesn't show on this project. However, the app icon showed on a different project
                                
                                    QIcon iconSet = _sysTrayIcon->icon();
                                    if ( iconSet.isNull()) {
                                        qDebug() << "ERROR : iconSet is NULL"; // this is not null
                                    }
                                }
                                

                                }
                                @

                                1 Reply Last reply Reply Quote 0
                                • SGaist
                                  SGaist Lifetime Qt Champion last edited by

                                  The path to the icon is relative, so it's very likely that it's not found at runtime.

                                  Interested in AI ? www.idiap.ch
                                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                  1 Reply Last reply Reply Quote 0
                                  • Q
                                    qt_sur last edited by

                                    So it turns out that I just had to include the ":" in the file path:

                                    @ QIcon sysIconToSet(":sysicon.png");
                                    @

                                    ":/sysicon.png" also worked.

                                    I wished Qt gave slightly better warning/compilation/run time errors. I was allocating the file paths similar to how many QML asset paths get set. Didn't find any note for the paths on the documentation either. But oh well, I should be able to get somewhere now.

                                    Thanks for your help. I will close off the thread.

                                    1 Reply Last reply Reply Quote 0
                                    • SGaist
                                      SGaist Lifetime Qt Champion last edited by

                                      The Qt Resource System chapter talks about that.

                                      You're welcome !

                                      Interested in AI ? www.idiap.ch
                                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                      1 Reply Last reply Reply Quote 0
                                      • First post
                                        Last post