En esta
entrada expliqué cómo comenzar con PyQt creando un sencillo QHolaMundo. Ahora voy a explicar cómo usar QtDesigner para recrear nuestro QHolaMundo.
Voy a asumir que ya se tiene instalado Python y PyQt, como lo expliqué en el
primer post. En Windows el instalador de PyQt ya trae todas las herramientas necesarias. Para tener las herramientas de edición en Linux debemos instalar los siguientes paquetes:
- pyqt4-dev-tools
- designer-qt4
Ya con las herramientas, comenzamos abriendo el QtDesigner:
Seleccionamos la opción
Main Window para obtener esto:
Así podremos comenzar a editar nuestra interfaz gráfica. Lo primero que necesitamos (para emular el QHolaMundo original) es un QBoxLayout horizontal. Vamos a las herramientas de la izquierda y arrastramos un
Horizontal Layout a nuestra ventana:
Ahora debemos indicarle a nuestra ventana que este layout será su layout por defecto. En la esquina superior derecha del editor encontramos el
Object Inspector
Allí seleccionamos nuestra ventana principal (
MainWindow) y hacemos clic derecho sobre ella. Aparece un menú contextual en el cual haremos clic en
Lay out > Lay out horizontally.
Ahora pondremos los widgets que necesitamos dentro de nuestro layout. En el
QHolaMundo original eran un
QLineEdit y un
QPushButton. Ambos se encuentran en el panel de herramientas:
En el panel de propiedades de la derecha, le pondremos nombres a nuestros componentes
Para preservar los nombres del
QHolaMundo original, al campo de texto lo llamaremos
leMiNombre y al botón
btHola. Ahora viene lo qué hace de QtDesigner tan buen editor: vamos a crear el evento de saludar y lo conectaremos al botón. En QtDesigner todo es visual, hasta esto.
Comencemos con crear un
slot. Un slot en Qt es una función que puede ser llamada por un evento (
signal). Podemos decir que en Qt los eventos se llaman signals y los métodos que ejecutan éstos son slots. Todo widget puede tener sus signals y slots personalizados. Lo que haremos es crearle un slot a nuestra ventana que se encargará de saludar al usuario. Para ello volvamos al
Object Inspector
Volvemos a hacer clic derecho sobre
MainWindow, en el menú contextual hacemos clic en
Change signals/slots para abrir este diálogo:
Como vemos en la imagen, hacemos clic en el símbolo + verde de los
slots para que se agregue un nuevo slot. Lo renombraremos como
salude() (debe incluir los paréntesis, esto indica que el slot no recibe parámetros). Aceptamos y ahora nos vamos al modo de edición
Signals/Slots ubicado en el toolbar superior
El primer botón de este toolbar es el diseño de componentes estándar. El segundo es el diseño de Signals/Slots. El tercero y el cuarto no lo usaremos por ahora. Al activar el modo de edición de Signals/Slots, haremos clic sostenido sobre el botón y arrastraremos el mouse sobre el espacio vacío de la ventana y allí soltaremos el botón del mouse. Al hacerlo correctamente aparecerá el siguiente cuadro:
Lo que hemos hecho (según muestra el conector rojo), es asociar una señal (signal) del botón a un método (slot) en la ventana. Ahora debemos seleccionar
clicked() como la señal a esperar y
salude() como nuestro slot receptor, y aceptamos.
Con esto es suficiente de QtDesigner para nuestro sencillo QHolaMundo. Guardamos el archivo en la carpeta que desee. Nos dirigimos a ella y abrimos una ventana de terminal (recordemos que en Windows Vista/7 se abre haciendo
clic derecho+Shift sobre la carpeta y luego
Abrir ventana de comandos aquí).
Ahora haremos uso de la consola para convertir nuestro archivo GUI guardado (que debe tener extensión
ui si no la cambió) en un script Python. Para ello usaremos la herramienta
pyuic4 que viene en la instalación de Windows. En Windows ejecutamos en la consola:
C:\Python25\Lib\site-packages\PyQt4\bin\pyuic4 QHolaMundo.ui -o QHolaMundoGui.py
Esto porque yo tengo Python 2.5, si instaló Python 2.6 se reemplaza
Python25 por
Python26, y lo mismo con el 2.7. En Linux es más fácil ya que pyuic4 ya está en el path del sistema:
pyuic4 QHolaMundo.ui -o QHolaMundoGui.py
Ahora tendrá un script de python en la misma carpeta donde guardó el
ui, llamado
QHolaMundoGui.py. A continuación necesitamos ejecutar este aplicativo. Vamos a crear un nuevo script de python en la misma carpeta llamado
QHolaMundo.py con el siguiente contenido:
from PyQt4.QtGui import *
import sys
from QHolaMundoGui import Ui_MainWindow
class QHolaMundo(QMainWindow):
def __init__(self):
QMainWindow.__init__(self,None)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
def salude(self):
miNombre = self.ui.leMiNombre.text()
saludo = 'Hola %s'%(miNombre)
QMessageBox.information(self,'Saludo',saludo)
app = QApplication(sys.argv)
qhm = QHolaMundo()
qhm.show()
sys.exit(app.exec_())
Encontremos las diferencias con el
QHolaMundo original (las he resaltado). Para comenzar, creamos la clase heredada de
QMainWindow y no de
QWidget, esto porque en el QtDesigner creamos un
Main Window. Además hemos reemplazado la creación de los widgets por dos líneas:
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
Lo que hacemos es crear en la propiedad
ui de nuestra clase el constructor de widgets (
Ui_MainWindow que es la clase que creó pyuic4 en QHolaMundoGui.py). Luego le indicamos que inicialice los widgets en nuestra ventana y listo, ahora nuestra ventana tiene la apariencia que le dimos en QtDesigner. La diferencia con hacerlo directamente (como el
QHolaMundo original) es que ahora los widgets no están en la misma ventana, sino dentro de la propiedad
ui, es decir, ahora no llamamos al campo de texto con
self.leMiNombre, sino con
self.ui.leMiNombre. Algo para nada molesto si tenemos en cuenta que nos ha ahorrado código.
Además vemos ahora que no hay que hacer conexiones con signals y slots. QtDesigner ya lo hizo por nosotros, lo único que necesitamos (de no hacerlo saltan errores al ejecutar) es crear en nuestra clase un método por cada slot que hayamos creado en QtDesigner. En este ejemplo sólo fue uno:
salude() y como vemos, no recibe parámetros.
Al ejecutar:
Como el original pero más fácil y divertido. Hay muchas más cosas que explorar con QtDesigner, como el exportador de recursos (pyrcc4), una opción muy interesante. En otra oportunidad haremos un navegador usando las librerías WebKit (las de Google Chrome y Safari) que vienen incluidas en PyQt, con QtDesigner.
TIP: si se trabaja mucho con QtDesigner resultará molesto en Windows estar llamando a pyuic4 y pyrcc4 desde su ubicación cada que se desea exportar un archivo ui. Hay soluciones como hacer el comando de exportación en un archivo bat, pero yo prefiero agregar la ubicación del pyuic4 (en mi equipo es C:\Python25\Lib\site-packages\PyQt4\bin) al path del sistema (como en Linux). Así desde donde quiero llamo a pyuic4 por su nombre, sin la dirección completa.