domingo, mayo 13, 2007

PyQt, usando interfases creadas con Designer

Una vez que creamos un archivo .ui en QtDesigner, existen dos formas de usarlo en nuestra aplicación:
  1. Compilarlo con pyuic
  2. Cargarlo dinámicamente mediante el modulo PyQt4.uic
Vemos el punto 1. Vamos a la consola, en el directorio donde hallamos guardado el .ui con el Designer, ejecutamos:
pyuic mi_archivo.ui
Si tienen ambas versiones de PyQt, quizás el comando sea pyuic4, si les da el error:
pyuic: File generated with too recent version of Qt Designer (4.0 vs. 3.3.7)
Vemos que todo el código es lanzado por la salida estándar, para eso usaremos el operador > para mostrarlo:
pyuic mi_archivo.ui > mi_clase.py
Muy bien, ahora tendremos las clase, mi_clase que tendrá en su interior la clase que inicializa la interfase sobre el widget que hemos elegido como base (QDialog, QWidget, QMainWidget...).
Ahora desde la consola python en el mismo directorio podemos hacer:

[nahuel@valhalla ~]$ python
Python 2.4.4 (#2, Jan 13 2007, 17:50:26)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyQt4.QtGui import *
>>> from PyQt4.QtCore import *
>>> import mi_clase
>>> dir(mi_clase)
['QtCore', 'QtGui', 'Ui_Form', '__builtins__', '__doc__', '__file__', '__name__', 'sys']
>>> class MiVentana(QWidget, mi_clase.Ui_Form):
... """ Heredo del Widget y de la clase que compile con pyuic """
... def __init__(self, *args):
... # Lo primero es llamar al padre
... QWidget.__init__(self, *args)
... # ahora uso un metodo que define Ui_Form para generar la interfase
... self.setupUi(self)
... print "Creacion de una ventana" # un mensajito como para avisar
...
>>> # ahora creamos el contexto de aplicacion Qt (QApplication)
...
>>> import sys
>>> app = QApplication(sys.argv)
>>> v = MiVentana()
Creacion de una ventana
>>> # ohhh, magico, no?
...
>>> v.show()
>>> # a correr.......
...
>>> app.exec_()
0

y obtenemos esto:
Bueno, aquí también les dejo el UI, que como verán es un XML.


Ahora vamos con el método dinámico(2), ya que se han tragado estos ultimos 3 posts sobre PyQt vamos a comenzar a ir más rápdio, si se complica me avisan, ok?

[nahuel@valhalla ~]$ python
Python 2.4.4 (#2, Jan 13 2007, 17:50:26)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from PyQt4.QtCore import *
>>> from PyQt4.QtGui import *
>>> # El modulo compilador de UIs
...
>>> from PyQt4 import uic
>>> # Veamos que tiene
...
>>> dir(uic)
['Compiler', 'PYQT_VERSION_STR', 'StringIO', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__path__', '_display_code', '_header', 'compileUi', 'compiler', 'exceptions', 'indenter', 'loadUi', 'loadUiType', 'objcreator', 'properties', 'time', 'uiparser']
>>> # Veamos la documentacion del metodo que usaremos...
...
>>> uic.loadUi.__doc__
'loadUi(uifile, baseinstance=None) -> widget\n\n Load a Qt Designer .ui file and return an instance of the user interface.\n\n uifile is a file name or file-like object containing the .ui file.\n baseinstance is an optional instance of the Qt base class. If specified\n then the user interface is created in it. Otherwise a new instance of the\n base class is automatically created.\n '
>>> # Bueno, vamos a probarlo
...
>>> import sys
>>> app = QApplication(sys.argv)
>>> ventana = uic.loadUi('./mi_clase.ui')
>>> ventana.show()
>>> app.exec_()
0
>>>
Espero que se hallan divertido viendo la flexibilidad que tiene PyQt para generar interfases.
Si están dudando que mecanismo usar el dinámico o el compilado, eso va a depender de que tan frecuentemente cambien la GUI. Los más osados podrían recompilar dinámicamente su .ui y de esa manera emular un Makefile...
Bueno, no les complico más, hagan los ejemplos, y cualquier problema me avisan,

2 comentarios:

GaStOn dijo...

Genial, me re sirvio el post, muchas gracias!!

nahuel dijo...

Hola Nahuel.. nada más escribo para decirte que me sorprendió encontrar un tocayo argentino, linuxero, pythonero y pyqt'ero. Yo sigo pythoneando pero Qt hace bastante que no uso.. si buscas en los archivos de la mailing list seguro me vas a ver renegando con memory leaks de la librería. Que suerte que diferamos en el apellido :).