PyQt – Ícono en el área de notificaciones (System tray)

Versión: Python 2.x, 3.x y PyQt 4.

Generalmente denominado system tray, se trata de un área específica de la pantalla en donde el sistema operativo permite a los programas enviar notificaciones.

System tray
System tray

Como puede observarse en las imágenes, las notificaciones están asociadas al ícono de la aplicación que, además, puede incluir menús contextuales.

Qt nos provee una implementación multiplataforma para crear este tipo de íconos y notificaciones mientras sean soportadas por el sistema operativo. Microsoft Windows es la plataforma con mayor soporte; las principales distribuciones de Linux también incluyen esta funcionalidad, al igual que sistemas Mac OS X.

Todas las funciones relacionadas con el system tray las provee la clase QSystemTrayIcon correspondiente al módulo QtGui.

from PyQt4.QtGui import QSystemTrayIcon

La función estática isSystemTrayAvailable nos indica si las funcionalidades del módulo son soportadas por el sistema operativo.

>>> QSystemTrayIcon.isSystemTrayAvailable()
True

Estaremos utilizando en este artículo el siguiente programa básico de Qt para implementar las funciones del área de notificaciones.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

from PyQt4.QtGui import QApplication, QIcon, QMainWindow, QSystemTrayIcon


class MainWindow(QMainWindow):
    
    def __init__(self):
        QMainWindow.__init__(self)
        
        # Incluir aquí código adicional


if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

Ahora bien, si tu sistema soporta esta funcionalidad, lo primero que necesitamos es un ícono que identifique a nuestra aplicación en el área de notificaciones. Yo estaré utilizando el siguiente perteneciente al IDE Eclipse (descargar ícono).

Eclipse IDE

Para crear un objeto del tipo QSystemTrayIcon es necesario indicarle un ícono del tipo QIcon seguido de la ventana padre.

        self.systray = QSystemTrayIcon(QIcon("icon.ico"), self)

Importando previamente las clases necesarias.

from PyQt4.QtGui import QApplication, QIcon, QMainWindow, QSystemTrayIcon

Sin más, una llamada a la función show mostrará nuestro ícono en el área de notificaciones.

Vista previa

Dado que el ícono solo no es de mucha utilidad, agregaremos un mensaje de bienvenida al momento de iniciar el programa, indicando primero el título y luego el texto.

        self.systray.showMessage("Mi programa",
            "Este es un mensaje de prueba.")

Vista previa

El mensaje puede incluir íconos de información (por defecto), advertencia, error o bien ninguno, utilizando la constante correspondiente como tercer argumento (NoIcon, Information, Warning y Critical).

        self.systray.showMessage("Mi programa",
            "Ha ocurrido un error.", QSystemTrayIcon.Critical)

Vista previa

Para realizar una determinada acción cuando el mensaje es presionado por el usuario, se utiliza la señal messageClicked.

        self.systray.showMessage("Mi programa",
            "Presiona en este mensaje para configurar.",
            QSystemTrayIcon.Warning)
        self.systray.messageClicked.connect(self.message_clicked)

    def message_clicked(self):
        print("Has presionado el mensaje.")

Vista previa

Por último, la función setContextMenu permite integrar un menú contextual (instancia de la clase QMenu) con múltiples opciones. A modo de ejemplo, nuestra opción del menú dará la posibilidad de ocultar el ícono utilizando la función hide.

        # Crear el menú contextual.
        self.systray_menu = QMenu(self)
        # Añadir la opción.
        self.hide_systray = self.systray_menu.addAction("Ocultar")
        # Conectar con la función hide al ser presionado.
        self.hide_systray.triggered.connect(self.systray.hide)
        # Establecer en el objeto systray.
        self.systray.setContextMenu(self.systray_menu)

E importar previamente la clase QMenu.

from PyQt4.QtGui import (QApplication, QIcon, QMainWindow, QMenu,
                         QSystemTrayIcon)

Vista previa

Código completo:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import sys

from PyQt4.QtGui import (QApplication, QIcon, QMainWindow, QMenu,
                         QSystemTrayIcon)


class MainWindow(QMainWindow):
    
    def __init__(self):
        QMainWindow.__init__(self)
        
        self.systray = QSystemTrayIcon(QIcon("icon.ico"), self)
        self.systray.show()
        self.systray.showMessage("Mi programa",
            "Presiona en este mensaje para configurar.",
            QSystemTrayIcon.Warning)
        self.systray.messageClicked.connect(self.message_clicked)
        
        # Crear el menú contextual.
        self.systray_menu = QMenu(self)
        # Añadir la opción.
        self.hide_systray = self.systray_menu.addAction("Ocultar")
        # Conectar con la función hide al ser presionado.
        self.hide_systray.triggered.connect(self.systray.hide)
        # Establecer en el objeto systray.
        self.systray.setContextMenu(self.systray_menu)

    def message_clicked(self):
        print("Has presionado el mensaje.")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

Curso online 👨‍💻

¡Ya lanzamos el curso oficial de Recursos Python en Udemy! Un curso moderno para aprender Python desde cero con programación orientada a objetos, SQL y tkinter en 2024.

Consultoría 💡

Ofrecemos servicios profesionales de desarrollo y capacitación en Python a personas y empresas. Consultanos por tu proyecto.

Deja una respuesta