domingo, 14 de agosto de 2011

Mi primer Hola Mundo con PyQt

Hasta hace poco para desarrollar aplicativos de escritorio en Python usaba la confiable librería wxPython. Se trata de una librería GUI que usa las ventanas nativas de Windows o GTK, según el sistema donde se corra. Como dije, es confiable y está muy desarrollada. Sin embargo, en mi opinión, se ha desarrollado un poco desordenado y esto hace que algunos componentes no se comunique bien con otros.

Hace un par de años, buscando un reemplazo fiable a wxPython, instalé PyQt. Cuando lo probé me impresionó su editor gráfico, el QtDesigner, que viene en el archivo de instalación para Windows. En aquella época trabajaba mucho Flash y necesitaba un GUI que me permitiera embeber un reproductor Flash como un Activex. PyQt tiene una versión comercial que permite hacer eso, pero por desgracia, la versión libre no lo permite. Así que lo deseché.

Hace unos meses le dí una nueva oportunidad y encontré una librería muy rica en componentes y posibilidades, y lo mejor, muy ordenada y coherente. Aún no puedo embeber un Flash, al menos no hasta que pague la licencia que no es extremadamente costosa (350 libras), pero hay que evaluar si vale la pena pagarla sólo para embeber Flash. Por fortuna hace unos días descubrí como usar Flash en PyQt sin comprar ni quebrantar la licencia (sólo en Windows), pero eso será tema de otra entrada.

Ahora veremos cómo hacer un Hola Mundo muy sencillo en PyQt sin usar el diseñador de interfaces. Lo primero que necesitamos son los ingredientes. Yo uso Python 2.5 que, en mi opinión, es la mejor versión de Python para Windows:
  • Python (recomiendo la 2.5). Para evitar complicaciones en Windows, es mejor usar el instalador que ofrece Activestate, es más fácil de instalar y trae la librería Win32.
  • PyQt (última versión). La versión de Windows trae el QtDesigner y un demo.
En Linux es más fácil, Python ya viene instalado (la versión 2.7 es perfecta para este SO y es la que trae Ubuntu), y PyQt se encuentra en los repositorios.

Una vez se instalen los ingredientes, creamos un nuevo script de python y lo llamamos QHolaMundo.py. Lo primero que hacemos es importar la librería PyQt:

from PyQt4.QtGui import *
from PyQt4.QtCore import *

También importamos el módulo sys:

import sys

Luego creamos una ventana sencilla:

class QHolaMundo(QWidget):
    def __init__(self):
        QWidget.__init__(self,None)
        layout = QBoxLayout(QBoxLayout.LeftToRight)
        self.leMiNombre = QLineEdit(self)
        self.btHola = QPushButton('Hola...',self)
        layout.addWidget(self.leMiNombre)
        layout.addWidget(self.btHola)
        self.setLayout(layout)

La ventana hereda de QWidget que es el componente básico de Qt. Creamos un QBoxLayout que será el que organice nuestros componentes dentro de la ventana. Creamos un QLineEdit que es el campo de texto donde introduciremos nuestro nombre. Luego un QPushButton (un botón común y corriente) que hará la acción de saludar. Estos dos componentes (widgets) se los agregamos al layout y luego asociamos el layout a nuestra ventana.

Por ahora esta ventana no hace nada, pero ejecutémosla para probar si funciona. Para ello necesitamos agregar el siguiente código al final del módulo:

app = QApplication(sys.argv)
qhm = QHolaMundo()
qhm.show()
sys.exit(app.exec_())

Esto lo que hace es crear un QApplication, que administrará la ejecución de PyQt. Le debemos pasar los argumentos del sistema, para ello necesitábamos al módulo sys.

Todo el código completo queda así:

from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys

class QHolaMundo(QWidget):
    def __init__(self):
        QWidget.__init__(self,None)
        layout = QBoxLayout(QBoxLayout.LeftToRight)
        self.leMiNombre = QLineEdit(self)
        self.btHola = QPushButton('Hola...',self)
        layout.addWidget(self.leMiNombre)
        layout.addWidget(self.btHola)
        self.setLayout(layout)

app = QApplication(sys.argv)
qhm = QHolaMundo()
qhm.show()
sys.exit(app.exec_())

Finalmente ejecutamos desde la línea de comandos con: python QHolaMundo.py y este es el resultado:
Si hacemos clic en el botón, aún no hace nada, y es que necesitamos hacer la función que salude y conectarla al botón. Nuestra función de saludo (dentro de la clase QHolaMundo):

def salude(self):
        miNombre = self.leMiNombre.text()
        saludo = 'Hola %s'%(miNombre)
        QMessageBox.information(self,'Saludo',saludo)

Este método toma lo que haya escrito el usuario en el campo de texto, lo adiciona al saludo ('Hola %s' donde %s se reemplaza por miNombre) y lo muestra en un cuadro de mensaje típico.

Ahora hacemos que el botón llame a esta función así (dentro de la función __init__ de la clase QHolaMundo):

QObject.connect(self.btHola,SIGNAL('clicked()'),self.salude)

De esta forma hacemos que btHola ejecute el método self.salude, cuando se de la señal 'clicked()' (clic en el botón). El código completo actualizado es este:

from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys

class QHolaMundo(QWidget):
    def __init__(self):
        QWidget.__init__(self,None)
        layout = QBoxLayout(QBoxLayout.LeftToRight)
        self.leMiNombre = QLineEdit(self)
        self.btHola = QPushButton('Hola...',self)
        layout.addWidget(self.leMiNombre)
        layout.addWidget(self.btHola)
        self.setLayout(layout)
        QObject.connect(self.btHola,SIGNAL('clicked()'),self.salude)
    def salude(self):
        miNombre = self.leMiNombre.text()
        saludo = 'Hola %s'%(miNombre)
        QMessageBox.information(self,'Saludo',saludo)

app = QApplication(sys.argv)
qhm = QHolaMundo()
qhm.show()
sys.exit(app.exec_())

Al ejecutarlo y presionar el botón:
Así de simple. Para más información sobre las clases se puede consultar la documentación en la página oficial de PyQt.

En posteriores entradas explicaré un poco más sobre PyQt, el uso del QtDesigner y cómo conectarse con Flash Player.

1 comentario:

Si deseas extender esta entrada, por favor hazlo