jueves, 15 de mayo de 2014

Agregar un evento a un Widget en PyQt4

Este post tiene por propósito explicar de manera simple como agregar un evento a un Widget de PyQt4, respetando las formas de dicha biblioteca.

Tomaremos un Qlabel de la biblioteca standart de Qt4 y le incorporaremos el evento click, buscando que este se comporte de manera similar al evento “clicked()” del QPushButton, por lo tanto, no solo debemos capturar dicho evento, sino también emitir una señal.

Comenzaremos construyendo una clase, la cual heredará de QLabel.


from PyQt4 import QtCore, QtGui

class NewLabel(QtGui.QLabel):

    def __init__(self, firstLabel,parent):
        QtGui.QLabel.__init__(self, firstLabel, parent)


Hemos heredado de QtGui.QLabel y sobrescrito el constructor, en el caso de una QLabel el primer parámetro hace referencia al texto que este mostrará y el segundo a quién es el Widget que contendrá dicho elemento. Este parámetro suele ser pasado como None en el caso de que un Widget sea contenido por un Layout.

Generaremos un módulo Main.py a solo efecto de poder incorporar nuestro NewLabel a una ventana del tipo QMainWindows.

import sys
from PyQt4 import QtGui
from NewLabel import NewLabel

def main():
    app = QtGui.QApplication(sys.argv)
    w = QtGui.QMainWindow()
    w.resize(400, 200)
    w.move(300, 300)
    w.setWindowTitle('Mi primer widget')
    #Creamos nuestra primer etiqueta
    new_label = NewLabel("Primer etiqueta", w)
    new_label.setStyleSheet("NewLabel {background-color:red;}")
    w.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()



Al ejecutar la aplicación se mostrará lo siguiente:





Hasta aquí solo hemos agregado una etiqueta del tipo NewLabel a la cual le modificamos, mediante el método StyleSheet, el color (es para diferenciarla de la ventana).

Antes de agregar el evento debemos hacer algunas aclaraciones. Existe una clase en Qt4 llamada QWidget la cual es la clase base de todos los elementos gráficos de Qt4, por lo tanto conociendo esto, podemos inferir que todos los métodos que nos brinda la clase base, estarán presentes en cualquier Widget de la biblioteca QtGui.

Para ampliar información sobre qué eventos es capaz de manejar esta clase, se recomienda el siguiente enlace:



El evento que necesitamos para cumplir con la consigna, es:

QWidget.mousePressEvent (self, QmouseEvent)

A pesar de que en este momento no lo utilizaremos, vale la pena destacar que el segundo parámetro recibido (QMouseEvent) cuenta con información del puntero del mouse, por citar alguna, las coordenadas X e Y.


from PyQt4 import QtCore, QtGui

class NewLabel(QtGui.QLabel):
    def __init__(self, firstLabel, parent = None):
        QtGui.QLabel.__init__(self, firstLabel, parent)

    def mousePressEvent(self, event):
        self.emit(QtCore.SIGNAL('clicked()'))


Como podemos ver en esta re-implementación del método mousePressEvent, emitimos la señal “clicked()”, a solo efecto de comportarnos de la misma forma que lo hace el QpushButton, de querer podríamos emitir cualquier señal.

Por último, nos resta modificar nuestro mádulo Main.py, conectando el evento “clicked() del NewLabel con un método capaz de imprimir por consola.


# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui, QtCore
from NewLabel import NewLabel

def imprimir():
print "CLICK"

def main():
    app = QtGui.QApplication(sys.argv)

    w = QtGui.QMainWindow()
    w.resize(400, 200)
    w.move(300, 300)
    w.setWindowTitle('Mi primer widget')
    #Creamos nuestra primer etiqueta
    new_label = NewLabel("Primer etiqueta", w)
    new_label.setStyleSheet("NewLabel {background-color:red;}")
    #Conectamos la señal con el lisener imprimir
    new_label.connect(new_label,\
                QtCore.SIGNAL("clicked()"),\
                imprimir)
    w.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()



Ya tenemos incorporado el evento “clicked()” a nuestro label.