Auf dieser Seite

Beispiel für ein Symbol in der Taskleiste

Das Beispiel „System-Tray-Symbol“ zeigt, wie man ein Symbol mit einem Menü und Popup-Meldungen zum System-Tray einer Desktop-Umgebung hinzufügt.

Popup-Meldung in der Taskleiste zu einem Netzwerkproblem

Screenshot des System-Tray-Symbols

Moderne Betriebssysteme bieten in der Regel einen speziellen Bereich auf dem Desktop, den sogenannten System-Tray oder Benachrichtigungsbereich, in dem lang laufende Anwendungen Symbole und Kurznachrichten anzeigen können.

Dieses Beispiel besteht aus einer einzigen Klasse, „ Window “, die das Hauptanwendungsfenster (d. h. einen Editor für das Symbol in der Taskleiste) und das zugehörige Symbol bereitstellt.

System-Tray-Editor zum Bearbeiten verschiedener Einstellungen wie Popup-Titel, Dauer und Meldung

Der Editor ermöglicht es dem Benutzer, das gewünschte Symbol auszuwählen sowie Art und Dauer der Sprechblasenmeldung festzulegen. Der Benutzer kann zudem den Titel und den Text der Meldung bearbeiten. Schließlich verfügt der Editor über ein Kontrollkästchen, mit dem gesteuert wird, ob das Symbol tatsächlich in der Taskleiste angezeigt wird oder nicht.

Definition der Fensterklasse

Die Klasse „ Window “ erbt von „ QWidget “:

class Window : public QDialog
{
    Q_OBJECT

public:
    Window();

    void setVisible(bool visible) override;

protected:
    void closeEvent(QCloseEvent *event) override;

private slots:
    void setIcon(int index);
    void iconActivated(QSystemTrayIcon::ActivationReason reason);
    void showMessage();
    void messageClicked();

private:
    void createIconGroupBox();
    void createMessageGroupBox();
    void createActions();
    void createTrayIcon();

    QGroupBox *iconGroupBox;
    QLabel *iconLabel;
    QComboBox *iconComboBox;
    QCheckBox *showIconCheckBox;

    QGroupBox *messageGroupBox;
    QLabel *typeLabel;
    QLabel *durationLabel;
    QLabel *durationWarningLabel;
    QLabel *titleLabel;
    QLabel *bodyLabel;
    QComboBox *typeComboBox;
    QSpinBox *durationSpinBox;
    QLineEdit *titleEdit;
    QTextEdit *bodyEdit;
    QPushButton *showMessageButton;

    QAction *minimizeAction;
    QAction *maximizeAction;
    QAction *restoreAction;
    QAction *quitAction;

    QSystemTrayIcon *trayIcon;
    QMenu *trayIconMenu;
};

Wir implementieren mehrere private Slots, um auf Benutzerinteraktionen zu reagieren. Die übrigen privaten Funktionen sind lediglich Hilfsfunktionen, die zur Vereinfachung des Konstruktors bereitgestellt werden.

Das Taskleisten-Symbol ist eine Instanz der Klasse „ QSystemTrayIcon “. Um zu prüfen, ob auf dem Desktop des Benutzers eine Taskleiste vorhanden ist, rufen Sie die statische Funktion „ QSystemTrayIcon::isSystemTrayAvailable()“ auf. In Verbindung mit dem Symbol stellen wir ein Menü bereit, das die typischen Aktionen „ minimize “, „ maximize “, „ restore “ und „ quit “ enthält. Wir implementieren die Funktion ` QWidget::setVisible()` neu, um das Menü des Taskleistensymbols zu aktualisieren, sobald sich das Erscheinungsbild des Editors ändert, z. B. beim Maximieren oder Minimieren des Hauptfensters der Anwendung.

Schließlich implementieren wir die Funktion ` closeEvent()` aus ` QWidget` neu, um den Benutzer (beim Schließen des Editorfensters) darüber informieren zu können, dass das Programm in der Taskleiste weiterläuft, bis der Benutzer den Eintrag „ Quit “ im Kontextmenü des Symbols auswählt.

Implementierung der Fensterklasse

Beim Erstellen des Editor-Widgets erstellen wir zunächst die verschiedenen Editor-Elemente, bevor wir das eigentliche Symbol in der Taskleiste erstellen:

Window::Window()
{
    createIconGroupBox();
    createMessageGroupBox();

    iconLabel->setMinimumWidth(durationLabel->sizeHint().width());

    createActions();
    createTrayIcon();

    connect(showMessageButton, &QAbstractButton::clicked, this, &Window::showMessage);
    connect(showIconCheckBox, &QAbstractButton::toggled, trayIcon, &QSystemTrayIcon::setVisible);
    connect(iconComboBox, &QComboBox::currentIndexChanged,
            this, &Window::setIcon);
    connect(trayIcon, &QSystemTrayIcon::messageClicked, this, &Window::messageClicked);
    connect(trayIcon, &QSystemTrayIcon::activated, this, &Window::iconActivated);

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->addWidget(iconGroupBox);
    mainLayout->addWidget(messageGroupBox);
    setLayout(mainLayout);

    iconComboBox->setCurrentIndex(1);
    trayIcon->show();

    setWindowTitle(tr("Systray"));
    resize(400, 300);
}

Wir stellen sicher, dass die Anwendung auf Benutzereingaben reagiert, indem wir die meisten Eingabe-Widgets des Editors (einschließlich des Taskleisten-Symbols) mit den privaten Slots der Anwendung verbinden. Beachten Sie jedoch das Kontrollkästchen „Sichtbarkeit“; dessen Signal „ toggled()“ ist stattdessen mit der Funktion „ setVisible()“ des Symbols verbunden.

void Window::setIcon(int index)
{
    QIcon icon = iconComboBox->itemIcon(index);
    trayIcon->setIcon(icon);
    setWindowIcon(icon);

    trayIcon->setToolTip(iconComboBox->itemText(index));
}

Der Slot „ setIcon() “ wird immer dann ausgelöst, wenn sich der aktuelle Index in der Symbol-Kombinationsfeld ändert, d. h. wenn der Benutzer ein anderes Symbol im Editor auswählt. Beachten Sie, dass er auch aufgerufen wird, wenn der Benutzer das Taskleistensymbol mit der linken Maustaste aktiviert, wodurch das Signal „ activated()“ des Symbols ausgelöst wird. Wir werden in Kürze auf dieses Signal zurückkommen.

Die Funktion ` QSystemTrayIcon::setIcon()` setzt die Eigenschaft ` icon `, die das eigentliche Taskleisten-Symbol enthält. Unter Windows beträgt die Größe des Taskleisten-Symbols 16x16; unter X11 ist die bevorzugte Größe 22x22. Das Symbol wird bei Bedarf auf die entsprechende Größe skaliert.

Beachten Sie, dass unter X11 aufgrund einer Einschränkung in der System-Tray-Spezifikation Mausklicks auf transparente Bereiche des Symbols an den System-Tray weitergeleitet werden. Sollte dieses Verhalten unerwünscht sein, empfehlen wir die Verwendung eines Symbols ohne Transparenz.

void Window::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason) {
    case QSystemTrayIcon::Trigger:
    case QSystemTrayIcon::DoubleClick:
        iconComboBox->setCurrentIndex((iconComboBox->currentIndex() + 1) % iconComboBox->count());
        break;
    case QSystemTrayIcon::MiddleClick:
        showMessage();
        break;
    default:
        ;
    }
}

Immer wenn der Benutzer das Symbol in der Taskleiste aktiviert, sendet es das Signal „ activated()“ aus und übergibt dabei den Auslösegrund als Parameter. „ QSystemTrayIcon “ stellt die Enumeration „ ActivationReason “ zur Verfügung, um zu beschreiben, wie das Symbol aktiviert wurde.

Im Konstruktor haben wir das Signal „ activated()“ unseres Symbols mit unserem benutzerdefinierten Slot „ iconActivated() “ verbunden: Hat der Benutzer mit der linken Maustaste auf das Symbol geklickt, ändert diese Funktion das Symbolbild, indem sie den aktuellen Index der Symbol-Combobox erhöht und dabei, wie oben erwähnt, den Slot „ setIcon() “ auslöst. Wenn der Benutzer das Symbol mit der mittleren Maustaste aktiviert, wird der benutzerdefinierte Slot „ showMessage() “ aufgerufen:

void Window::showMessage()
{
    showIconCheckBox->setChecked(true);
    int selectedIcon = typeComboBox->itemData(typeComboBox->currentIndex()).toInt();
    QSystemTrayIcon::MessageIcon msgIcon = QSystemTrayIcon::MessageIcon(selectedIcon);

    if (selectedIcon == -1) { // custom icon
        QIcon icon(iconComboBox->itemIcon(iconComboBox->currentIndex()));
        trayIcon->showMessage(titleEdit->text(), bodyEdit->toPlainText(), icon,
                          durationSpinBox->value() * 1000);
    } else {
        trayIcon->showMessage(titleEdit->text(), bodyEdit->toPlainText(), msgIcon,
                          durationSpinBox->value() * 1000);
    }
}

Wenn der Slot „showMessage()“ ausgelöst wird, rufen wir zunächst das entsprechende Symbol für den aktuell ausgewählten Nachrichtentyp ab. Die Enumeration „ QSystemTrayIcon::MessageIcon “ beschreibt das Symbol, das angezeigt wird, wenn eine Sprechblasenmeldung erscheint. Anschließend rufen wir die Funktion „ showMessage()“ von „ QSystemTrayIcon “ auf, um die Nachricht mit Titel, Text und Symbol für die in Millisekunden angegebene Zeit anzuzeigen.

Hinweis für macOS-Benutzer: Das Growl-Benachrichtigungssystem muss installiert sein, damit QSystemTrayIcon::showMessage() Nachrichten anzeigen kann.

QSystemTrayIcon verfügt außerdem über das entsprechende Signal „ messageClicked()“, das ausgelöst wird, wenn der Benutzer auf eine von „ showMessage()“ angezeigte Meldung klickt.

void Window::messageClicked()
{
    QMessageBox::information(nullptr, tr("Systray"),
                             tr("Sorry, I already gave what help I could.\n"
                                "Maybe you should try asking a human?"));
}

Im Konstruktor haben wir das Signal „ messageClicked()“ mit unserem benutzerdefinierten Slot „ messageClicked() “ verknüpft, der mithilfe der Klasse „ QMessageBox “ einfach eine Meldung anzeigt.

QMessageBox stellt einen modalen Dialog mit einer kurzen Meldung, einem Symbol und Schaltflächen bereit, deren Anordnung vom aktuellen Stil abhängt. Es unterstützt vier Schweregrade: „Frage“, „Information“, „Warnung“ und „Kritisch“. Der einfachste Weg, in Qt ein Meldungsfeld einzublenden, ist der Aufruf einer der zugehörigen statischen Funktionen, z. B. ` QMessageBox::information()`.

Wie bereits erwähnt, implementieren wir einige der virtuellen Funktionen von ` QWidget` neu:

void Window::setVisible(bool visible)
{
    minimizeAction->setEnabled(visible);
    maximizeAction->setEnabled(!isMaximized());
    restoreAction->setEnabled(isMaximized() || !visible);
    QDialog::setVisible(visible);
}

Unsere Neuimplementierung der Funktion ` QWidget::setVisible()` aktualisiert das Menü des Taskleistensymbols, sobald sich das Erscheinungsbild des Editors ändert – z. B. beim Maximieren oder Minimieren des Hauptfensters der Anwendung –, bevor die Implementierung der Basisklasse aufgerufen wird.

void Window::closeEvent(QCloseEvent *event)
{
    if (!event->spontaneous() || !isVisible())
        return;
    if (trayIcon->isVisible()) {
        QMessageBox::information(this, tr("Systray"),
                                 tr("The program will keep running in the "
                                    "system tray. To terminate the program, "
                                    "choose <b>Quit</b> in the context menu "
                                    "of the system tray entry."));
        hide();
        event->ignore();
    }
}

Wir haben den Ereignis-Handler ` QWidget::closeEvent()` neu implementiert, um Schließereignisse des Widgets zu empfangen, und zeigen den Benutzern die oben genannte Meldung an, wenn sie das Editorfenster schließen. Wir müssen vermeiden, die Meldung anzuzeigen und das Schließereignis zu akzeptieren, wenn der Benutzer die Anwendung tatsächlich beenden möchte: Das heißt, wenn der Benutzer „Beenden“ in der Menüleiste oder im Kontextmenü des Taskleistensymbols ausgelöst oder unter macOS die Tastenkombination „Befehl+Q“ gedrückt hat.

Zusätzlich zu den oben besprochenen Funktionen und Slots haben wir auch mehrere Hilfsfunktionen implementiert, um den Konstruktor zu vereinfachen: ` createIconGroupBox()`, ` createMessageGroupBox()`, ` createActions() ` und ` createTrayIcon()`. Details finden Sie in der Datei „ desktop/systray/window.cpp “.

Beispielprojekt @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.