Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [SOLVED] How to use QPlatformSystemTrayIcon or QSystemTrayIcon with Qt Quick Application?

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

Scheduled Pinned Locked Moved QML and Qt Quick
17 Posts 3 Posters 6.0k Views
  • 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.
  • SGaistS Offline
    SGaistS Offline
    SGaist
    Lifetime Qt Champion
    wrote on last edited by
    #8

    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
    0
    • Q Offline
      Q Offline
      qt_sur
      wrote on last edited by
      #9

      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
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #10

        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
        0
        • Q Offline
          Q Offline
          qt_sur
          wrote on last edited by
          #11

          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
          0
          • Q Offline
            Q Offline
            qt_sur
            wrote on last edited by
            #12

            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
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #13

              @
              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
              0
              • Q Offline
                Q Offline
                qt_sur
                wrote on last edited by
                #14

                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
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #15

                  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
                  0
                  • Q Offline
                    Q Offline
                    qt_sur
                    wrote on last edited by
                    #16

                    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
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #17

                      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
                      0

                      • Login

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • Users
                      • Groups
                      • Search
                      • Get Qt Extensions
                      • Unsolved