PyQT5 Responder a Eventos

Una de las tareas más comunes a la hora de crear una GUI es responder a determinados eventos para dar cierta funcionalidad a nuestra aplicación, por ejemplo: ejecutar una acción al presionar un botón, o incluso responder a eventos que no han sido producidos por la GUI como los eventos de conexión o desconexión a la red de internet.

Signals & slots


Este es el mecanismo utilizado por PyQT5 para responder y manejar eventos ocurridos en nuestra aplicación, un signal es emitido cuando se produce un evento, ejemplo: un click, y un slot es un método que conectaremos a un signal para que este se ejecute cada vez que se produzca un determinado evento.

Para ejemplificar lo que hemos escrito crearemos una pequeña QUI con un botón, responderemos al evento click mostrando un simple cuadro de mensajes.

class Example(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        btn1 = QPushButton("Button 1", self)
        btn1.resize(150, 40)
        btn1.move(400 / 2 - 150 / 2, 200 / 2 - 40 / 2)
        btn1.clicked.connect(self.buttonClicked)

        self.resize(400, 200)
        self.setMaximumSize(400, 200)
        self.setWindowTitle('Event PyQT5')
        self.show()

    def buttonClicked(self, e):
        QMessageBox.information(self, 'Events - Slot', 'click en Button 1.')

El código: btn1.clicked.connect(self.buttonClicked) es usado para conectar el signal clicked (se produce al hacer clic sobre btn1) con el slot buttonClicked (método que se ejecutará cuando ocurra el evento).

Utilizamos un cuadro de dialogo informativo para indicar al usuario cundo se ha hecho clic sobre el botón, QMessageBox.information(self, 'Events - Slot', 'click en Button 1.'), existen varios tipos de QMessageBox como warning para mostrar una advertencia o question para realizar una pregunta al usuario.

Otra manera de responder a un evento es sobrescribir el método manejador del evento, por ejemplo, nuestra ventana extiende la clase QWidget, esta utiliza el método closeEvent(self, event) para responder al evento que se produce cuando el usuario hace clic sobre el botón de cerrar (X), la acción es cerrar la ventana, podemos sobrescribir este método para que tenga un comportamiento diferente, por ejemplo: preguntar al usuario si realmente desea cerrar la aplicación.

def closeEvent(self, event):
    reply = QMessageBox.question(self,
                                 'Events - Slot',
                                 "Realmente desea cerrar la aplicacion",
                                  QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
    if reply == QMessageBox.Yes:
        event.accept()
    else:
        event.ignore()

Utilizamos otro tipo de QMessageBox, esta vez el usuario tendrá la opción de responder “Yes” o “No”, obtenemos la respuesta en la variable que devuelve QMessageBox.question, de ser afirmativa cerramos la ventana, event.accept() para aceptar el evento, no hacemos nada en caso contrario, event.ignore() para omitir este evento.

pyqt5 event slot
En ocasiones necesitamos información sobre quien genera el evento, podríamos conectar dos o más signal a un mismo slot, si deseáramos saber cuál ha generado el evento podemos usar el método self.sender() que devuelve el objeto que generó el signal.

He agregado un segundo botón a la GUI, ambos están conectados al mismo slot, para saber cuál es el botón que ha producido el evento clic usamos self.sender(), luego usaremos el método text para obtener el texto que contiene el botón y mostrarlo en el cuadro de mensaje informativo.

def buttonClicked(self, e):
    btn_txt = self.sender().text()
    QMessageBox.information(self, 'Events - Slot', 'click en: ' + btn_txt)

Normalmente también necesitamos información sobre el evento que se ha producido, por ejemplo: keyPress es el signal que se produce cada vez que se presiona una tecla, sobrescribiremos el método keyPressEvent para controlar este evento, deseamos que la ventana se cierre al presionar la tecla ESC, por lo que necesitamos la información sobre la tecla presionada, si la tecla ESC cerramos la ventana.

def keyPressEvent(self, event):
    if event.key() == Qt.Key_Escape:
        self.close()

La variable event es la que contiene la información del evento producido, en este caso el evento es keyPress por lo que esta variable contendrá información sobre la tecla presionada, obtenemos la tecla presionada con event.key() y verificamos si se trata de la tecla ESC para cerrar la ventana.

GitHub: Responder a Eventos PyQT5

Comentarios

  1. Estoy empezando con PyQt5 y el tutorial es estupendo. Claro y Preciso. sldos;

    ResponderEliminar
  2. Hola tengo una duda, si tengo dos ventanas, una dentro de la otra, al apretar un click en una, como le envio la informacion a la ventana que lo contiene? aqui te dejo un link donde esta publicada esta pregunta https://es.stackoverflow.com/questions/84283/pasar-informaci%C3%B3n-de-un-qdialog-a-su-padre-qmainwindow
    gracias de antemano

    ResponderEliminar
  3. Este comentario ha sido eliminado por el autor.

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Conectar SQL Server con Java

Entrenar OpenCV en Detección de Objetos

Detección de figuras geométricas

Procesamiento de imágenes en OpenCV

Conociendo la clase cv::Mat de OpenCV