Using QSystemTrayIcon for System Tray Icons in Qt Widgets Applications


What is QSystemTrayIcon?

In Qt for desktop applications, QSystemTrayIcon is a class that enables you to create an icon for your application in the system tray (also known as the notification area). This icon provides a convenient way for users to interact with your application in the background, without needing a full-fledged window.

Key Functionalities

  • Visibility Control
    Manage the visibility of the icon in the system tray with show() and hide().
  • Balloon Messages
    Display temporary messages with titles, bodies, and optional icons using showMessage().
  • Tooltips
    Offer informative tooltips that appear when users hover over the icon using setToolTip().
  • Context Menus
    Provide a context menu with relevant actions for users to interact with your application by calling setContextMenu().
  • Icon Display
    Set a custom icon for your application using setIcon().

Using QSystemTrayIcon

  1. #include <QApplication>
    #include <QSystemTrayIcon>
    
  2. Create an Instance

    QApplication app(argc, argv); // Initialize Qt application
    QSystemTrayIcon trayIcon; // Create a system tray icon object
    
  3. Optional: Check System Tray Availability

    if (QSystemTrayIcon::isSystemTrayAvailable()) {
        // System tray is available, proceed with customization
    } else {
        // System tray unavailable, inform the user (optional)
    }
    
  4. Set Icon and Context Menu

    trayIcon.setIcon(QIcon(":/path/to/your/icon.png")); // Set custom icon
    
    QMenu* menu = new QMenu; // Create a context menu
    menu->addAction("Show Main Window"); // Add menu actions
    trayIcon.setContextMenu(menu);
    
  5. Connect Signals and Slots (Optional)
    Connect signals emitted by QSystemTrayIcon to your application's slots to handle user interactions (e.g., clicking the icon or menu items).

  6. Show the Icon

    trayIcon.show(); // Make the icon visible in the system tray
    

Additional Considerations

  • Explore other QSystemTrayIcon methods for fine-tuning the icon's behavior, such as setting a tooltip, displaying balloon messages, and managing visibility based on application state.
  • Remember to manage the lifetime of the QMenu object you create for the context menu.


#include <QApplication>
#include <QSystemTrayIcon>
#include <QMenu>
#include <QMainWindow>

class MyMainWindow : public QMainWindow {
    Q_OBJECT

public:
    MyMainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {}

private slots:
    void showMainWindow() {
        this->show();
    }

    void quitApplication() {
        qApp->quit();
    }
};

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

    // Check system tray availability (optional)
    if (!QSystemTrayIcon::isSystemTrayAvailable()) {
        qDebug() << "System tray unavailable";
        return 1;
    }

    QSystemTrayIcon trayIcon;
    trayIcon.setIcon(QIcon(":/icon.png")); // Replace with your icon path

    // Create context menu
    QMenu* menu = new QMenu;
    menu->addAction("Show Main Window", &app, SLOT(showMainWindow()));
    menu->addAction("Quit", &app, SLOT(quitApplication()));
    trayIcon.setContextMenu(menu);

    // Connect to icon activation signal
    QObject::connect(&trayIcon, &QSystemTrayIcon::activated, &trayIcon, [=](QSystemTrayIcon::ActivationReason reason) {
        if (reason == QSystemTrayIcon::Trigger) {
            // Icon clicked, show main window
            app.activeWindow()->show();
        }
    });

    trayIcon.setToolTip("My Application");
    trayIcon.show();

    MyMainWindow window;
    window.hide(); // Initially hide the main window

    return app.exec();
}
  1. Include Headers
    Necessary headers for Qt application, system tray icon, context menu, and main window.
  2. Create Main Window
    A subclass MyMainWindow inherits from QMainWindow for your application's main window.
  3. Main Function
    Initializes the Qt application and checks for system tray availability.
  4. Create and Configure Tray Icon
    • Creates a QSystemTrayIcon object.
    • Sets a custom icon using setIcon().
    • Creates a context menu with actions using QMenu and adds them.
    • Sets the context menu to the tray icon using setContextMenu().
    • Connects the activated signal of the tray icon to a lambda function to handle clicks.
    • Sets a tooltip using setToolTip().
    • Shows the tray icon using show().
  5. Create and Hide Main Window
    Creates an instance of MyMainWindow and hides it initially (you might want to show it differently based on your application logic).
  6. Start Application
    Executes the Qt application's main event loop (app.exec()).
  • This is a basic example. You can customize it further based on your specific needs, such as adding balloon messages, setting different icons based on application state, and handling other signals emitted by QSystemTrayIcon.
  • Replace ":/icon.png" with the actual path to your icon image.


Custom Window (Less Preferred)

  • This approach is generally less desirable due to:
    • Potential conflicts with the actual system tray behavior.
    • Requires more manual handling of window positioning and interaction.
  • Create a small, borderless window that mimics the behavior of a system tray icon.

Native Platform APIs (Advanced)

  • This approach requires a deeper understanding of the underlying platform APIs and can lead to less portable code.
  • If you need more fine-grained control or platform-specific features beyond what QSystemTrayIcon offers, you can interact with the native platform APIs (e.g., Windows Shell API, XEmbed on Linux) directly.

Third-Party Libraries (Explore with Caution)

  • Be cautious when choosing libraries to ensure they are actively maintained and compatible with your Qt version.
  • Explore third-party libraries specifically designed for system tray icon management.
ApproachProsCons
QSystemTrayIconRecommended, well-supported by Qt, easy to useMay have limitations depending on your specific needs
Custom WindowLess preferred, provides more controlLess user-friendly, potential conflicts
Native Platform APIsAdvanced, fine-grained controlRequires deeper platform knowledge, less portable
Third-Party LibrariesMay offer additional featuresRequires careful selection and maintenance