Convertir archivo de Qt Designer (.ui) a código de fuente Python (.py)



Versión: 2.x, 3.x

Introducción

La herramienta pyuic convierte automáticamente archivos de Qt Designer (.ui) a archivos de código de fuente Python (.py). Se distribuye junto a PyQt, forma parte del conjunto de herramientas que éste provee. Su utilización es de lo más sencilla. Se pasa como argumento el nombre del archivo .ui al llamar a pyuic.py y éste imprime el resultado (código de fuente Python) en la salida estándar, o en un archivo determinado por la opción -o.

Antes de continuar con su utilización, recuerda (en la medida de lo posible) nunca editar el código generado por pyuic, sino moverlo a donde corresponda e importarlo luego desde un archivo encargado de inicializar la clase.

Conversión

Para seguir esta guía es necesario, primero, tener un archivo .ui (generado por Qt Designer) para poder convertirlo a código fuente. Si no, puedes utilizar un supuesto reproductor que he diseñado yo, descargándolo desde este enlace. El mismo se ve de la siguiente manera:

Vista previa

Si haces la prueba de abrir reproductor.ui (o cualquier otro archivo de Qt Designer) con un editor de texto verás que simplemente es un archivo XML, que contiene la información de cada uno de los widgets (controles) y su ubicación. Por ejemplo, observa cómo se ve parte de mi archivo:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>589</width>
    <height>394</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Reproductor de audio</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QListView" name="listView">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>40</y>
      <width>481</width>
      <height>271</height>
     </rect>
    </property>
   </widget>
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>10</x>
      <y>20</y>
      <width>46</width>
      <height>13</height>
     </rect>
    </property>
    <property name="text">
     <string>Pistas:</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_2">
    <property name="geometry">
     <rect>
      <x>500</x>
      <y>40</y>
      <width>46</width>
      <height>13</height>
     </rect>
    </property>
    <property name="text">
     <string>Opciones</string>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>500</x>
      <y>70</y>
      <width>75</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>Reproducir</string>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton_2">
    <property name="geometry">
     <rect>
      <x>500</x>
      <y>100</y>
      <width>75</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>Pausa</string>
    </property>
   </widget>
 <!-- ... -->
 </widget>
 <resources/>
 <connections/>
</ui>

Como segunda instancia, debemos hallar el script pyuic.py.

En Windows, una vez en la carpeta de instalación de Python, lo encontrarás en Lib\site-packages\PyQt4\uic. Por ejemplo, C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py.

En Linux, probablemente se encuentre en usr/lib/pythonX.Y/dist-packages/PyQt4/uic, donde X e Y corresponden al número de versión. Por ejemplo, usr/lib/python2.7/dist-packages/PyQt4/uic/pyuic.py.

Una vez que lo hayas localizado, ejecuta la terminal. Ahora simplemente resta hacer la llamada al script indicándole el archivo que deseamos convertir. La estructura es la siguiente:

python pyuic.py [opciones] archivo.ui

También es posible invocar al convertidor pasando opción -m al intérprete.

python -m PyQt4.uic.pyuic -o [opciones] archivo.ui

Ésta es la forma preferente para usuarios de PyQt5.

python -m PyQt5.uic.pyuic -o [opciones] archivo.ui

En nuestro caso, utilizaremos:

python pyuic.py -o archivo.py archivo.ui

De esta manera pyuic leerá archivo.ui y lo convertirá en un nuevo fichero llamado archivo.py. Probablemente debas usar la ruta completa. Algunos ejemplos:

Windows

> python C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py -o C:\reproductor.py C:\reproductor.ui

> cd C:\Python27\Lib\site-packages\PyQt4\uic
> python pyuic.py C:\reproductor.py C:\reproductor.ui

> cd C:\
> python C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py -o reproductor.py reproductor.ui

Linux

$cd Documentos
$python /usr/lib/python2.7/dist-packages/PyQt4/uic/pyuic.py -o reproductor.py reproductor.ui

$ cd /usr/lib/python2.7/dist-packages/PyQt4/uic
$ python pyuic.py -o /home/usuario/Documentos/reproductor.py /home/usuario/Documentos/reproductor.ui

python /usr/lib/python2.7/dist-packages/PyQt4/uic/pyuic.py -o reproductor.py reproductor.ui

Al finalizar, en mi caso, el nuevo archivo creado reproductor.py se ve de la siguiente manera:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'reproductor.ui'
#
# Created: Sat May 03 17:07:19 2014
#      by: PyQt4 UI code generator 4.10.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(589, 394)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.listView = QtGui.QListView(self.centralwidget)
        self.listView.setGeometry(QtCore.QRect(10, 40, 481, 271))
        self.listView.setObjectName(_fromUtf8("listView"))
        self.label = QtGui.QLabel(self.centralwidget)
        self.label.setGeometry(QtCore.QRect(10, 20, 46, 13))
        self.label.setObjectName(_fromUtf8("label"))
        self.label_2 = QtGui.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(500, 40, 46, 13))
        self.label_2.setObjectName(_fromUtf8("label_2"))
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(500, 70, 75, 23))
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.pushButton_2 = QtGui.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(500, 100, 75, 23))
        self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
        self.pushButton_3 = QtGui.QPushButton(self.centralwidget)
        self.pushButton_3.setGeometry(QtCore.QRect(500, 130, 75, 23))
        self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
        self.label_3 = QtGui.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(10, 330, 46, 13))
        self.label_3.setObjectName(_fromUtf8("label_3"))
        self.horizontalSlider = QtGui.QSlider(self.centralwidget)
        self.horizontalSlider.setGeometry(QtCore.QRect(60, 325, 160, 22))
        self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
        self.horizontalSlider.setObjectName(_fromUtf8("horizontalSlider"))
        self.lcdNumber = QtGui.QLCDNumber(self.centralwidget)
        self.lcdNumber.setGeometry(QtCore.QRect(430, 320, 64, 23))
        self.lcdNumber.setStyleSheet(_fromUtf8("color: rgb(255, 0, 0);\n"
"background-color: rgb(0, 0, 0);"))
        self.lcdNumber.setProperty("value", 2315.0)
        self.lcdNumber.setObjectName(_fromUtf8("lcdNumber"))
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 589, 21))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "Reproductor de audio", None))
        self.label.setText(_translate("MainWindow", "Pistas:", None))
        self.label_2.setText(_translate("MainWindow", "Opciones", None))
        self.pushButton.setText(_translate("MainWindow", "Reproducir", None))
        self.pushButton_2.setText(_translate("MainWindow", "Pausa", None))
        self.pushButton_3.setText(_translate("MainWindow", "Detener", None))
        self.label_3.setText(_translate("MainWindow", "Volumen:", None))

Aplicación

Nada sucederá si intentas ejecutar el archivo de código de fuente Python que ha generado pyuic. Para visualizar la interfaz, primero debes crear una aplicación de PyQt e importar la clase generada. En mi caso, crearé un archivo llamado main.py en el mismo directorio que reproductor.py con el siguiente código.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from PyQt4.QtGui import QApplication, QMainWindow

from reproductor import Ui_MainWindow


if __name__ == "__main__":
    app = QApplication([])
    window = QMainWindow()
    main_window = Ui_MainWindow()
    main_window.setupUi(window)
    window.show()
    app.exec_()

Finalmente, lo ejecuto: python main.py. El resultado es:

Vista previa
Vista previa



14 comentarios.

  1. Buenas, estoy comenzando a trabajar con python y quiero integrarlo con una GUI. Decidí usar PyQt, con el Qt Designer, pero tengo un problema. Cuando intento convertir de .ui a .py,, tal y como usted indica en su artículo, me lanza este mensaje de error:
    Traceback (most recent call last):
    File “C:\Python27\Lib\site-packages\PyQt4\uic\pyuic.py”, line 31, in
    from PyQt4 import QtCore
    ImportError: DLL load failed: %1 no es una aplicaci¾n Win32 vßlida.

    He probado con todas las variantes que he encontrado, pero si no me da este error me da otro. He buscado en otros sitios, pero no he hallado una solución para mi problema, así que ahora busco su ayuda. Espero su respuesta. Muchas gracias por adelantado.

  2. hola muchas gracias por la publicación, estuve revisando estos días sobre Python y Qt, precisamente por mi parte hago desde Elementary OS la conversión en terminal con pyuic4 archivo.ui -o archivo.py y me va bien; lo que si no ví en tu entrada es como lo haces funcional, entiendo que al crear un lanzador vas a poder llamar a la ventana archivo.py que ya has creado y se va a mostrar bien en tu sistema operativo, pero ¿cómo haces que funcione? , me parece que no esta claro o yo no entendí, esperando que te encuentres muy bien me despido, un saludo.

    • Recursos Python says:

      Hola. En este caso el reproductor es solo un ejemplo: no tiene ninguna funcionalidad real, si es eso a lo que te refieres.

      Saludos

    • Recursos Python says:

      Sacando la posibilidad de editar el código, ninguna. Ambos métodos funcionan perfectamente bien. Claro, si deseas distribuir tu aplicación, entonces también tendrás que incluir tu archivo .ui.

      Saludos.

  3. He creado una interface de botones, llamados GUI pickers para animadores 3D, en QT Designer. He creado un archivo *.ui
    Pero necesito convertirlo en archivo *.py, para Maya o Blender lo reconozca
    Con estos scripts es posible???

    • Recursos Python says:

      Hola. Sí, la herramienta pyuic es justamente para convertir archivos de Qt Designer a archivos de código de fuente de Python. Desconozco cómo funcionan Blender o Maya.

      Un saludo.

  4. debería haber alguna forma de obtener el archivo .py sin tantas vueltas. se debería poder tener al código fuente de inmediato sin hacer esos procesos en consola cmd.

  5. Muchas gracias por tu aporte! Estuve como media hora para poder montar la ventana desde PySide y no podía, por fin lo logre. Se agradece mucho tu aporte 😀

Deja un comentario