Beispiel für ein Systemablage-Symbol
Das Beispiel für das Systemleistensymbol zeigt, wie ein Symbol mit einem Menü und Popup-Meldungen in die Systemleiste einer Desktop-Umgebung eingefügt werden kann.
Screenshot des Systemleistensymbols
Moderne Betriebssysteme stellen in der Regel einen speziellen Bereich auf dem Desktop zur Verfügung, der als Systemtray oder Infobereich bezeichnet wird und 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 Taskleistensymbol) und das zugehörige Symbol bereitstellt.
Der Editor ermöglicht es dem Benutzer, das bevorzugte Symbol auszuwählen sowie den Typ und die Dauer der Ballonmeldung festzulegen. Der Benutzer kann auch den Titel und den Text der Nachricht bearbeiten. Schließlich bietet der Editor ein Kontrollkästchen, das steuert, 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 anderen privaten Funktionen sind lediglich Komfortfunktionen, die zur Vereinfachung des Konstruktors bereitgestellt werden.
Das Taskleistensymbol ist eine Instanz der Klasse QSystemTrayIcon. Um zu prüfen, ob ein System-Tray auf dem Desktop des Benutzers vorhanden ist, rufen Sie die statische Funktion QSystemTrayIcon::isSystemTrayAvailable() auf. Zusammen mit dem Symbol bieten wir ein Menü mit den typischen Aktionen minimize, maximize, restore und quit. Wir implementieren die Funktion QWidget::setVisible() neu, um das Menü des Tray-Symbols immer dann zu aktualisieren, wenn sich das Erscheinungsbild des Editors ändert, z. B. wenn das Hauptanwendungsfenster maximiert oder minimiert wird.
Schließlich wird die Funktion closeEvent() von QWidget neu implementiert, um den Benutzer (beim Schließen des Editor-Fensters) darüber zu informieren, dass das Programm im System-Tray weiterläuft, bis der Benutzer den Eintrag Quit im Kontextmenü des Symbols auswählt.
Implementierung der Fensterklasse
Bei der Konstruktion des Editor-Widgets erstellen wir zunächst die verschiedenen Editor-Elemente, bevor wir das eigentliche System-Tray-Symbol 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 Taskleistensymbols) mit den privaten Slots der Anwendung verbinden. Beachten Sie jedoch das Kontrollkästchen für die Sichtbarkeit; sein toggled()-Signal 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 Icon Combobox ändert, d.h. wenn der Benutzer ein anderes Icon im Editor auswählt. Beachten Sie, dass er auch aufgerufen wird, wenn der Benutzer das Tray-Symbol mit der linken Maustaste aktiviert, wodurch das Signal activated() des Symbols ausgelöst wird. Auf dieses Signal werden wir in Kürze zurückkommen.
Die Funktion QSystemTrayIcon::setIcon() setzt die Eigenschaft icon, die das eigentliche Taskleistensymbol enthält. Unter Windows ist die Größe des Taskleistensymbols 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 Spezifikation der Taskleiste Mausklicks auf transparente Bereiche des Symbols an die Taskleiste weitergegeben werden. Wenn dieses Verhalten inakzeptabel ist, 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 System-Tray-Symbol aktiviert, sendet es sein activated()-Signal und übergibt den auslösenden Grund als Parameter. QSystemTrayIcon bietet die Aufzählung ActivationReason, um zu beschreiben, wie das Symbol aktiviert wurde.
Im Konstruktor haben wir das activated()-Signal unseres Symbols mit unserem benutzerdefinierten iconActivated()
-Slot verbunden: Wenn der Benutzer das Icon mit der linken Maustaste angeklickt hat, ändert diese Funktion das Icon-Bild, indem sie den aktuellen Index der Icon-Combobox erhöht und den setIcon()
-Slot wie oben erwähnt auslöst. Aktiviert der Benutzer das Icon mit der mittleren Maustaste, 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 showMessage() -Slot ausgelöst wird, rufen wir zunächst das Nachrichtensymbol in Abhängigkeit vom aktuell gewählten Nachrichtentyp ab. Die Aufzählung QSystemTrayIcon::MessageIcon beschreibt das Symbol, das angezeigt wird, wenn eine Sprechblasenmeldung angezeigt wird. Dann rufen wir die Funktion QSystemTrayIcon's showMessage() auf, um die Nachricht mit dem Titel, dem Text und dem Symbol für die in Millisekunden angegebene Zeit anzuzeigen.
macOS-Benutzer beachten: Das Growl-Benachrichtigungssystem muss installiert sein, damit QSystemTrayIcon::showMessage() Nachrichten anzeigen kann.
QSystemTrayIcon hat auch das entsprechende Signal messageClicked(), das ausgegeben wird, wenn der Benutzer auf eine von showMessage() angezeigte Nachricht 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()
verbunden, der einfach eine Nachricht mit der Klasse QMessageBox anzeigt.
QMessageBox bietet einen modalen Dialog mit einer kurzen Nachricht, einem Symbol und Schaltflächen, die je nach aktuellem Stil angeordnet sind. Es werden vier Schweregrade unterstützt: "Frage", "Information", "Warnung" und "Kritisch". Der einfachste Weg, eine Messagebox in Qt zu öffnen, ist der Aufruf einer der zugehörigen statischen Funktionen, z.B. QMessageBox::information().
Wie wir bereits erwähnt haben, reimplementieren wir einige der virtuellen Funktionen von QWidget:
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 Tray-Icons immer dann, wenn sich das Erscheinungsbild des Editors ändert, z.B. beim Maximieren oder Minimieren des Hauptanwendungsfensters, 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 QWidget::closeEvent()-Ereignishandler neu implementiert, um Widget-Schließereignisse zu empfangen und den Benutzern die oben genannte Nachricht zu zeigen, wenn sie das Editor-Fenster schließen. Wir müssen es vermeiden, die Meldung anzuzeigen und das Schließereignis zu akzeptieren, wenn der Benutzer die Anwendung wirklich beenden will: das heißt, wenn der Benutzer "Beenden" in der Menüleiste oder im Kontextmenü des Tray-Symbols ausgelöst oder die Tastenkombination Befehl+Q unter macOS gedrückt hat.
Zusätzlich zu den oben besprochenen Funktionen und Slots haben wir auch einige Komfortfunktionen implementiert, um den Konstruktor zu vereinfachen: createIconGroupBox()
, createMessageGroupBox()
, createActions()
und createTrayIcon()
. Siehe die Datei desktop/systray/window.cpp
für weitere Details.
© 2025 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.