Python en Español

Tutorial de PyQt5- Ejemplos de programación con GUI de Python

En un tutorial anterior, hablamos acerca del módulo Tkinter y vimos cómo crear aplicaciones GUI usándolo. En este tutorial, continuaremos creando interfaces gráficas en Python y esta vez usaremos PyQt5.

PyQt5 es uno de los módulos más utilizados en la creación de aplicaciones con interfaces gráficas en Python y esto es debido a su simplicidad, como veras a continuación.


Otra gran característica que alienta a los desarrolladores a usar PyQt5 es el PyQt5 designer, que facilita el desarrollo de aplicaciones gráficas complejas en poco tiempo. Simplemente arrastras widgets para crear formularios.

En este tutorial de PyQt5, usaré Python 3.6 en Windows 10, ademas supongo que ya conoces algunos conceptos básicos de Python.

¡Suena genial ¿no? ! Entonces, comencemos, instalemos PyQt5 primero y luego veremos cómo desarrollar la interfaces graficas GUI de aplicaciones con ejemplos.

 

 

Instalar PyQt5

PyQt5 tiene dos versiones, la versión comercial y la versión GPL gratuita que usaremos en este tutorial.

Para instalar PyQt5, existen dos maneras:

  • Usando pip
  • Usando el código fuente

Usando pip

Para instalar PyQt5 usando pip, ejecuta el siguiente comando:

$ pip3 install PyQt5

Para asegurarte de que la instalación exitosa, ejecuta el siguiente código de Python:

import PyQt5

Si no aparecieron errores, eso significa que instalaste PyQt5 correctamente, pero si aparece algún error, puedes estar usando una versión no compatible de Python.

Utilizar el código fuente (en Linux)

Para instalar PyQt5 desde el código fuente, debes hacer lo siguiente:

  • Instalar SIP.
  • Descarga el código fuente de PyQt5.
  • Configurar e instalar.

Como sabrás, PyQt5 es un enlace de Python para la famosa biblioteca Qt que está escrita en C ++. La herramienta que hace este enlace se llama SIP.

Entonces, para instalar PyQt5 desde el código fuente, primero necesitas instalar SIP.

Para instalar SIP, ejecuta el siguiente comando:

$ pip3 install PyQt5-sip

Ahora estás listo para descargar e instalar el código fuente de PyQt5.

Descarga el código fuente de PyQt5 desde aquí.

Luego, descomprimelo y ejecuta los siguientes comandos dentro de la raíz de la carpeta resultante de la descompresión:


Para asegurarte de que todo está bien, intenta importar PyQt5 como hicimos antes y todo debería estar bien.

Usar el código fuente (en Windows)

Dado que SIP necesita el compilador GCC, debes instalar MinGW que es una versión de Windows del compilador GCC de Linux.

Lo único que hay que cambiar es el paso de configuración; Necesitas decirle a Python acerca de la plataforma.

Esto se puede hacer de la siguiente forma:


¡Felicidades! instalaste PyQt5 correctamente desde el código fuente.

 


Instalar Pyqt5 designer

Hay dos formas de crear aplicaciones con interfaces gráficas utilizando PyQt5:

  • Diseñar widgets por código.
  • Utilizar PyQt5 designer.

En este tutorial de PyQt5, usaremos PyQt5 designer, que hace que sea muy fácil terminar una gran cantidad de trabajo en cuestión de segundos.

El PyQt5 designer viene incluido con las herramientas de PyQt5. Para instalarlo, necesitas instalar las herramientas de PyQt5.

$ pip3 install PyQt5-tools

¿Dónde está el PyQt5 designer?

Después de la instalación, puedes encontrar el PyQt5 designer en esta ubicación:

C:\Program Files\Python36\Lib\site-packages\pyqt5-tools\

Además, si instalaste Python solo para tu usuario actual, encontrarás el PyQt5 designer en esta ubicación:

C:\Users\LikeGeeks\AppData\Local\Programs\Python\Python36-32\Lib\site-packages\ pyqt5-tools\

Puedes crear un acceso directo a este programa en lugar de ir a esta ubicación cada vez que quieras ejecutarlo.

 


Cómo utilizar PyQt5 designer

Abre el archivo designer.exe y verás un cuadro de diálogo que te pregunta acerca de la plantilla de formulario que deseas utilizar.

PyQt5 Designer

Hay cinco plantillas disponibles:

  • Cuadro de diálogo con botones en la parte inferior: crea un formulario con los botones Aceptar y Cancelar en la parte inferior derecha del formulario.
  • Cuadro de diálogo con botones a la derecha: crea un formulario con los botones Aceptar y Cancelar en la parte superior derecha del formulario.
  • Cuadro de diálogo sin botones: crea un formulario en blanco.
  • Ventana principal: crea una ventana con una barra de menús y una barra de herramientas, la cual se hereda de QMainWindow.
  • Widget: crea un widget que se hereda de la clase QWidget, a diferencia de las plantillas de diálogos que se heredan de la clase QDialog.

Entonces, tenemos tres tipos de plantillas, ¿cuál es la diferencia?

La diferencia entre QDialog, QMainWindow y QWidget

  • QWidget es la clase base que se utiliza para todos los elementos de la GUI en el PyQt5.
  • QDialog se utiliza para preguntar al usuario sobre algo, como pedirle que acepte o rechace algo o tal vez pedir algun input, esta plantilla tiene como clase base QWidget.
  • QMainWindow es la plantilla más grande en donde puedes colocar tu barra de herramientas, barra de menú, barra de estado y otros widgets, no tiene un margen incorporado para botones como los de QDialog.

 


Cargar .ui VS convertir .ui a .py

En este tutorial, usaremos el PyQt5 designer, pero antes de profundizar, veamos cómo utilizaremos el diseño generado por este programa.

Abre PyQt5 designer, elige la plantilla de la Main Window y haz clic en el botón crear.

Luego desde el menú de archivo, haz clic en guardar; El PyQt5 designer exportará tu formulario a un archivo XML con la extensión .ui. Ahora, para usar este diseño, tienes dos formas:

  • Cargar el archivo .ui en tu código Python.
  • Convertir el archivo .ui en un archivo .py utilizando pyuic5.

Cargar el archivo .ui en tu código Python

Para cargar el archivo .ui en tu código Python, puedes utilizar la función loadUI () de uic de esta manera:


Si ejecutas tu código, deberías ver una ventana con nada más que una etiqueta.

¡Eso significa que el archivo ui fue cargado correctamente!

Utilizaremos sys.exit (app.exec ()) en lugar de usar app.exec () directamente para enviar el código de estado correcto al proceso principal o al proceso de llamada.

Si utilizaste app.exec () directamente, la aplicación respondera con cero, lo que significa que tuvo éxito, y esto ocurrirá incluso si la aplicación falla.

Convertir archivos .ui en un archivo .py usando pyuic5

Ahora, intentemos la segunda forma al convertir el archivo .ui a un archivo de código Python:

$ pyuic5 mydesign.ui -o mydesign.py

¡Sí! Se creó un nuevo archivo con el nombre mydesign.py. Ahora, importemos ese archivo para mostrar nuestra ventana.

Pyuic5 significa la versión 5 del convertidor de interfaz de usuario de Python.


Si ejecutas este código, deberías ver la misma ventana nuevamente como lo hicimos en el primer método.

La ventaja de utilizar el segundo método es la autocompletación que proporcionará el IDE, ya que todos los widgets son importados, mientras que el primer método es el que solo carga el archivo .ui y necesitarás conocer los nombres de widgets.

Otro beneficio de utilizar el segundo método es la velocidad, ya que no necesita hacer un análisis XML para cargar la interfaz de usuario.

¡Así que podemos decir que convertir el archivo .ui en un archivo .py es más seguro en la codificación y más rápido en la carga!Haz click para twittear

Ahora, ensuciémonos un poco las manos y juguemos con los widgets de PyQt5.

 

QLabel widget

Para agregar un widget de QLabel a tu formulario, haz lo siguiente:

  • Abre PyQt5 designer y elige la plantilla de Main Window (Pantalla principal).
  • Arrastra un widget de label (etiqueta) desde el cuadro de widgets de la izquierda.

Ahora, guarda el diseño en un archivo .ui y conviértelo en un archivo .py para jugar con el codigo del widget.

Cambiar la Fuente

Para cambiar la fuente del QLabel, utiliza el método setFont () y pásale como parámetro un QFont de esta manera:


Si ejecutas este código, notarás que la etiqueta no aparece correctamente porque su tamaño es más pequeño que el tamaño de fuente que usamos. Debido a esto, tenemos que establecer el tamaño de la etiqueta.

Cambiar tamaño

Para cambiar el tamaño del QLabel, necesitas modificar su geometría usando el método setGeometry () de esta manera:


Cambiar tamaño

Cambiar texto

Modificar el texto de un QLabel se puede realizar usando el método setText () de la siguiente manera:


Cambiar texto

¡Eso fue fácil! Veamos algunos otros widgets.

 


Widget QLineEdit

QLineEdit es un lugar campo donde puedes aceptar datos ingresados por el usuario. LineEdit tiene muchos métodos para trabajar.

Crearé un nuevo diseño PyQt5 designer y agregaré seis widgets QLineEdit y ademas, lo exportaré a un archivo .py.

Ahora, veamos algunos métodos de QLineEdit:


QLineEdit

Al primer QlineEdit le cambiamos el texto usando el método setText ().

En el segundo QlineEdit, establecimos el número máximo de caracteres permitidos a 10 para que no se acepte nada más.

El tercer QlineEdit, lo configuramos en modo de contraseña para que los datos de entrada sean asteriscos.

El cuarto QlineEdit, lo configuramos en solo lectura para que no se pueda editar su contenido.

El quinto QlineEdit, cambiamos el color de la fuente utilizando el método setStyleSheet () e insertamos el color como valores CSS de las páginas web.

El sexto QlineEdit, cambiamos el color de fondo usando el método setStyleSheet ().

El método setStyleSheet ()

El método setStyleSheet () se puede usar con todos los widgets de PyQt5 para cambiar su estilo.

Lo que se muestra a continuación es lo que puedes modificar con el método setStyleSheet ():

  • Tipo de letra y tamaño
  • Color del texto
  • Color del Fondo
  • Color del borde
  • Color del borde superior
  • Color del borde inferior
  • Color del borde derecho
  • Color del borde izquierdo
  • Selección del color del fondo

Estos son los valores más importantes que puede pasar al método setStyleSheet ().

 

QPushButton Widget

La mayoría de tus programas Python tendrán este widget QPushButton. Haz click en el botón y se ejecutará algún código.

Si tienes experiencia en la programación, debes haber escuchado acerca del manejo de eventos en los que interactúas con un widget y se ejecuta una función.

La idea en PyQt5 es la misma pero las definiciones son un poco diferentes.

Haz click para twittear

Cuando haces click en un QPushButton, se emite una signal. El nombre de la signal en este caso se llama clicked().

Para vincular la signal con un slot, debes utilizar el método connect() como se mostrara a continuación verá ahora.

Este proceso de manejo de eventos continúa funcionando hasta que cierres el formulario o widget principal.

Construyamos un formulario con un QLabel y un QPushButton y exportémoslo a un archivo .py.

Ahora, conectaremos el signal clicked() con un slot utilizando el método connect() de la siguiente forma:

self.ui.pushButton.clicked.connect(self.btnClicked)

El btnClicked es el slot o la función que se ejecutará cuando se haga clic en el QPushButton.

Entonces tu código estará estructurado así:


¡Increíble!

 


Visual Signal / editor de slots

Vimos cómo conectar la señal del widget a una ranura utilizando el método connect (), pero esta no es la única manera.

En realidad, hay algunos slots predefinidos para cada widget. Puedes conectar una signal a cualquier slot predefinida sin codificación utilizando el PyQt5 designer.

Arrastra un QPushButton y un QLineEdit a tu formulario. Presione F4 y arrastre el mouse desde el QPushButton y suéltelo en la parte superior del QLineEdit.

Aparecerá el editor de signal / slot.

editor de slots

A la izquierda están las signals predefinidas mientras que a la derecha los slots predefinidas. Digamos que queremos conectar la signal clicked() con el slot clear.

Elige clicked de la izquierda y clear de la derecha y haz click en OK.

Luego de finalizar tus conexiones signal/slot, puedes salir de este modo presionando la tecla ESC o F3.

Ahora, si ejecutas este formulario y haces click en el QPushButton, cualquier texto en el QLineEdit sera borrado. Puedes editar o borrar esta conexión en el panel del editor de signal/slot.

 

Como emitir una signal

Ya vimos como funcionan las signals y los slots. Todas las signals con que trabajamos fueron predefinidas por nosotros.

¿ Pero como podemos emitir nuestra propia signal personalizada?

¡Muy fácil! Puedes hacerlo utilizando la clase pyqtSignal como se muestra a continuación:

  • Define tu propio tipo de evento con pyqtSignal.
  • Llama al método emit() en donde quieras que se active tu evento.

Digamos que tienes una clase nut y quieres activar la signal cracked cuando la rompemos.


 

Como utilizar una signal

Ahora, hagamos que nuestro ejemplo sea un poco mas practico al instanciar la clase nut y emitir la signal cracked:


La signal cracked fue emitida correctamente.

Sobrescritura de una Signal (event)

A veces necesitas sobrescribir el comportamiento que viene por defecto de una signal o de un evento.

Vamos a ver un ejemplo practico de eso. Si quieres cerrar la ventana principal cuando el usuario presiona una tecla en especifico, puedes sobrescribir el evento keyPressEvent dentro de tu ventana principal de la siguiente forma:


Ahora si presionas la tecla F12, la ventana principal se cerrara.

Aquí sobrescribimos la signal de pulsación de tecla de la ventana principal y cerramos la ventana.

 

Widget QComboBox

En lugar de permitir que el usuario ingrese valores en un QLineEdit o en cualquier widget editable, podemos usar un widget de QCombobBox para darle al usuario una lista de opciones para seleccionar.

Vamos a arrastrar un combo box a nuestro formulario y echar un vistazo a algunos de sus métodos.

Si ejecutas la aplicación en este momento, notarás que el QComboBox está vacío. Para agregar elementos al QComboBox, utiliza el método addItem():


QComboBox additem

Obtener todos los items

No hay un método directo para obtener todos los elementos de un QComboBox, pero puedes usar un ciclo for para hacerlo.


 

Seleccionar un item

Para seleccionar un elemento de QComboBox, tienes dos métodos:


Ten en cuenta que al seleccionar un elemento por texto debes de asegurarte de escribir el texto correcto de lo contrario el QComboBox se mantendrá en el primer elemento.

 

Widget QTable

Si deseas ver los datos de tu base de datos en un formato tabular, PyQt5 proporciona el QTableWidget para eso.

QTableWidget consta de celdas, cada celda es una instancia de la clase QTableWidgetItem.

Diseñemos un formulario que contenga un QTableWidget y un QPushButton. Arrastra un widget de tabla y un botón desde el cuadro de widgets. Luego guarda y convierte el diseño para usarlo.

Para agregar filas al QTableWidget, puede usar el método setRowCount ().

Para agregar columnas al QTableWidget, puedes usar el método setColumnCount ().


QTableWidget

Ahora puedes escribir texto manualmente dentro de las celdas QTableWidget.

Borrar contenido de un QtableWidget

Para borrar el contenido de un QTableWidget, puedes utilizar el método clear() de esta manera:


QTableWidget clear text

Poblar QTableWidget por código

Para poblar un QTableWidget mediante a traves del codigo debes usar el método setItem () para cada QTableWidgetItem.


Poblar QTableWidget por código

  • Primero, creamos una Lista de Python de tres tuplas.
  • Dentro del constructor de la ventana principal, configuramos el número de filas y columnas.
  • Luego iteramos sobre la lista y obtenemos cada tupla de la lista para llenar las celdas de la tabla usando el método setItem().
  • Finalmente, mostramos la ventana principal.

Hacer que el QTableWidget sea no editable (solo lectura)

Es posible que quieras dejar las celdas de la tabla editables para el usuario en algunos casos. Como lo puede ser el mostrar datos sensibles de solo lectura.

Para hacer que un QTableWidget no sea editable, puedes usar el método setFlags () para configurar cada QTableWidgetItem no editable.

cellinfo.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) #make it not editable

Debes establecer las banderas antes de configurar el contenido de tu celda.

Por lo tanto, el código ser verá de la siguiente manera:


Ahora, si intentas editar cualquier celda, no podrás; porque el QTableWidgetItem no es editable.

Establecer el nombre de la columna QTableWidget (encabezado)

Hasta ahora, los nombres de las columnas de QTableWidget son números. ¿Qué sucede si quieres tener tus propios nombres de columnas?.

Para configurar el texto del encabezado QTableWidget, puedes utilizar el método setHorizontalHeaderLabels() de esta manera:


QTableWidget set column header text

De la misma manera, puedes cambiar el encabezado de la fila usando el método setVerticalHeaderLabels():

self.ui.tableWidget.setVerticalHeaderLabels(('Row 1', 'Row 2', 'Row 3'))

Cómo ordenar un QTableWidget

Puede hacer que su QTableWidget pueda ordenarse utilizando el método setSortingEnabled().

self.ui.tableWidget.setSortingEnabled(True)

Cuando el usuario haga clic en el encabezado de una columna, puede ordenar los datos en orden ascendente o descendente.

Puedes utilizar este método antes o después de llenar el QTableWidget con datos.

¿Como podria entoces ordenar en base a una columna especifica del QTableWidget?

Puedes usar el método sortByColumn () tambien y configurar el índice de columna y el orden de clasificación de esta manera:


Además, puedes utilizar el método sortItems() para ordenar el QTableWidget en orden ascendente de forma predeterminada.

self.ui.tableWidget.sortItems(0)

O puedes especificar el orden de clasificación:

self.ui.tableWidget.sortItems(0,QtCore.Qt.DescendingOrder)

Tienes que tener en cuenta que si deseas ordenar tus columnas de forma programática, debes utilizar los métodos de clasificación después de llenar el QTableWidget con datos, de lo contrario, tus datos no se ordenarán.

 

Añadir un QComboBox en un QTableWidget

Es posible que necesite que el usuario elija un valor dentro del QTableWidget en lugar de ingresar un texto.

¿Como podriamos agregar un QComboBox dentro de un QTableWidgetItem?

Para agregar un QComboBox dentro de QTableWidgetItem, puedes usar el método setCellWidget():


Añadir un QComboBox en un QTableWidget

¡Genial!

No detengas tu imaginación y trata de insertar diferentes widgets como un QCheckbox o incluso un QProgressBar.

El código anterior será el mismo, excepto la línea donde creas el QComboBox, ahí deberás agregar el widget que desees.

Añadir un QProgessBar en un QTableWidgetAñadir un QCheckBox en un QTableWidget

El único límite es tu imaginación.

Empaquetado de archivos Python (Convertir a ejecutable)

Puedes convertir tus programas de Python en ejecutables binarios utilizando muchas herramientas.

Mi preferencia es la siguiente, usaré pyinstaller, que es capaz de empaquetar o congelar el código Python en un ejecutable bajo Windows, Linux, Mac OS X, FreeBSD y Solaris. Todo esto con soporte completo para la arquitectura de 32, 64 bits.

La mejor parte sobre pyinstaller es que tiene soporte completo para PyQt5.

¡Genial! Primero, instala pyinstaller:

$ pip3 install pyinstaller

Después de que lo hayas instalado, puedes convertir tus programas de Python de la siguiente forma:

$ pyinstaller test.py

El archivo ejecutable se generará en una carpeta llamada dist en tu directorio de programas de Python.

Muchas dependencias serán generadas junto al ejecutable. ¿Como podriamos hacer que fuera un solo archivo?

Puedes generar un archivo ejecutable usando un modo de archivo como este:

$ pyinstaller --onefile test.py

Cada vez que ejecuta el programa, aparecera una ventana de consola, ¿Como puedo ocultar esta ventana?

Puede usar -w o –noconsole para ocultar la ventana de la consola:

$ pyinstaller -w test.py

Esta opción existe solo para Windows y Mac OS X.

Pyinstaller ofrece muchas opciones para empaquetar tu aplicación, para enumerar todas las opciones, usa –help:

$ pyinstaller --help

Traté de mantener todo lo más simple posible. Espero que encuentres el tutorial útil.

Gracias.

Mokhtar Ebrahim
Estoy trabajando como administrador de sistemas Linux desde 2010. Soy responsable de mantener, proteger y solucionar problemas de servidores Linux para múltiples clientes de todo el mundo. Me encanta escribir guiones de shell y Python para automatizar mi trabajo.

2 thoughts on “Tutorial de PyQt5- Ejemplos de programación con GUI de Python

  1. Hola, bro. Te escribe un desarrollador de C++. En 2 horitas aprendí a desarrollar en Python, con un curso que encontré en la web. Y en 30 minutos aprendí a desarrollar interfaces gráficas, gracias a tu contenido. Excelente material! Gracias!

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *