Ejemplo de icono de la bandeja del sistema
El ejemplo del icono de la bandeja del sistema muestra cómo añadir un icono con un menú y mensajes emergentes a la bandeja del sistema de un entorno de escritorio.

Captura de pantalla del icono de la bandeja del sistema
Los sistemas operativos modernos suelen proporcionar un área especial en el escritorio, llamada bandeja del sistema o área de notificación, donde las aplicaciones de larga ejecución pueden mostrar iconos y mensajes cortos.
Este ejemplo consiste en una única clase, Window, que proporciona la ventana principal de la aplicación (es decir, un editor para el icono de la bandeja del sistema) y el icono asociado.

El editor permite al usuario elegir el icono preferido, así como establecer el tipo y la duración del mensaje del globo. El usuario también puede editar el título y el cuerpo del mensaje. Por último, el editor proporciona una casilla de verificación que controla si el icono se muestra realmente en la bandeja del sistema, o no.
Definición de la clase Window
La clase Window hereda de 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; };
Implementamos varias ranuras privadas para responder a la interacción del usuario. Las otras funciones privadas son sólo funciones de conveniencia proporcionadas para simplificar el constructor.
El icono de la bandeja es una instancia de la clase QSystemTrayIcon. Para comprobar si hay una bandeja del sistema en el escritorio del usuario, se llama a la función estática QSystemTrayIcon::isSystemTrayAvailable(). Asociado al icono, proporcionamos un menú que contiene las acciones típicas minimize, maximize, restore y quit. Reimplementamos la función QWidget::setVisible() para actualizar el menú del icono de la bandeja cada vez que cambia la apariencia del editor, por ejemplo, al maximizar o minimizar la ventana principal de la aplicación.
Por último, reimplementamos la función closeEvent() de QWidget para poder informar al usuario (al cerrar la ventana del editor) de que el programa seguirá ejecutándose en la bandeja del sistema hasta que el usuario elija la entrada Quit en el menú contextual del icono.
Implementación de la clase Window
Al construir el widget del editor, primero creamos los diversos elementos del editor antes de crear el icono real de la bandeja del sistema:
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); }
Nos aseguramos de que la aplicación responde a la entrada del usuario conectando la mayoría de los widgets de entrada del editor (incluyendo el icono de la bandeja del sistema) a las ranuras privadas de la aplicación. Pero fíjate en la casilla de visibilidad; su señal toggled() está conectada a la función setVisible() del icono.
void Window::setIcon(int index) { QIcon icon = iconComboBox->itemIcon(index); trayIcon->setIcon(icon); setWindowIcon(icon); trayIcon->setToolTip(iconComboBox->itemText(index)); }
La ranura setIcon() se activa cada vez que cambia el índice actual en el combobox de iconos, es decir, cada vez que el usuario elige otro icono en el editor. Observe que también se llama cuando el usuario activa el icono de la bandeja con el botón izquierdo del ratón, activando la señal activated() del icono. Volveremos a esta señal en breve.
La función QSystemTrayIcon::setIcon() establece la propiedad icon que contiene el icono actual de la bandeja del sistema. En Windows, el tamaño del icono de la bandeja del sistema es 16x16; en X11, el tamaño preferido es 22x22. El icono se escalará al tamaño apropiado según sea necesario.
Tenga en cuenta que en X11, debido a una limitación en la especificación de la bandeja del sistema, los clics del ratón en áreas transparentes del icono se propagan a la bandeja del sistema. Si este comportamiento es inaceptable, sugerimos utilizar un icono sin transparencia.
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: ; } }
Cada vez que el usuario activa el icono de la bandeja del sistema, éste emite su señal activated() pasando la razón desencadenante como parámetro. QSystemTrayIcon proporciona el enum ActivationReason para describir cómo se activó el icono.
En el constructor, conectamos la señal activated() de nuestro icono a nuestra ranura personalizada iconActivated(): Si el usuario ha pulsado el icono con el botón izquierdo del ratón, esta función cambia la imagen del icono incrementando el índice actual del combobox de iconos, activando el slot setIcon() como se ha mencionado anteriormente. Si el usuario activa el icono utilizando el botón central del ratón, se llama a la ranura personalizada showMessage():
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); } }
Cuando se activa la ranura showMessage(), primero recuperamos el icono del mensaje dependiendo del tipo de mensaje elegido en ese momento. El enum QSystemTrayIcon::MessageIcon describe el icono que se muestra cuando se visualiza un mensaje de globo. A continuación, llamamos a la función QSystemTrayIcon's showMessage() para mostrar el mensaje con el título, el cuerpo y el icono durante el tiempo especificado en milisegundos.
Nota para los usuarios de macOS: El sistema de notificaciones Growl debe estar instalado para que QSystemTrayIcon::showMessage() muestre mensajes.
QSystemTrayIcon también tiene la señal correspondiente, messageClicked(), que se emite cuando el usuario hace clic en un mensaje mostrado por showMessage().
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?")); }
En el constructor, conectamos la señal messageClicked() a nuestra ranura personalizada messageClicked() que simplemente muestra un mensaje utilizando la clase QMessageBox.
QMessageBox proporciona un diálogo modal con un mensaje corto, un icono y botones dispuestos en función del estilo actual. Admite cuatro niveles de gravedad: "Pregunta", "Información", "Advertencia" y "Crítico". La forma más sencilla de abrir un cuadro de mensaje en Qt es llamar a una de las funciones estáticas asociadas, por ejemplo, QMessageBox::information().
Como mencionamos anteriormente, reimplementamos un par de funciones virtuales de QWidget:
void Window::setVisible(bool visible) { minimizeAction->setEnabled(visible); maximizeAction->setEnabled(!isMaximized()); restoreAction->setEnabled(isMaximized() || !visible); QDialog::setVisible(visible); }
Nuestra reimplementación de la función QWidget::setVisible() actualiza el menú del icono de la bandeja cada vez que cambia la apariencia del editor, por ejemplo, al maximizar o minimizar la ventana principal de la aplicación, antes de llamar a la implementación de la clase base.
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(); } }
Hemos reimplementado el manejador de eventos QWidget::closeEvent() para recibir eventos de cierre del widget, mostrando el mensaje anterior a los usuarios cuando cierran la ventana del editor. Tenemos que evitar mostrar el mensaje y aceptar el evento de cierre cuando el usuario realmente tiene la intención de salir de la aplicación: es decir, cuando el usuario ha activado "Salir" en la barra de menús, o en el menú contextual del icono de la bandeja, o pulsado Comando+Q en macOS.
Además de las funciones y ranuras comentadas anteriormente, también hemos implementado varias funciones de conveniencia para simplificar el constructor: createIconGroupBox(), createMessageGroupBox(), createActions() y createTrayIcon(). Véase el archivo desktop/systray/window.cpp para más detalles.
© 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.