Tutorial de PyQt5 con ejemplos: Diseño de GUI usando PyQt en Python

¿Qué es PyQt?

PyQt es un enlace de Python del kit de herramientas de widgets de código abierto Qt, que también funciona como un marco de desarrollo de aplicaciones multiplataforma. Qt es un popular C++ marco para escribir aplicaciones GUI para las principales plataformas integradas, móviles y de escritorio (compatible con Linux, Windows, Mac OS, Android, iOS, Raspberry Pi y más).

PyQt es un software gratuito desarrollado y mantenido por Riverbank Computing, una empresa con sede en Inglaterra, mientras que Qt es desarrollado por una empresa finlandesa llamada The Qt Company.

Características de PyQT

Estas son las características importantes de PyQt:

Aprenda PyQt, que consta de más de seiscientas clases que cubren una variedad de características como

  • Interfaces gráficas de usuario
  • Bases de datos SQL
  • Kits de herramientas web
  • Procesamiento XML
  • Networking

Estas funciones se pueden combinar para crear interfaces de usuario avanzadas y aplicaciones independientes. Muchas empresas importantes de todos los sectores utilizan Qt. Algunos ejemplos son LG, Mercedes, AMD, Panasonic, Harman, etc.

Versiones de PyQt

PyQt está disponible en dos ediciones, PyQt4 y PyQt5. PyQt4 proporciona un código adhesivo para vincular las versiones 4.xy 5.x del marco Qt, mientras que PyQt5 proporciona un vínculo solo para las versiones 5.x. Como resultado, PyQt5 no es compatible con los módulos obsoletos de la versión anterior. En este tutorial de Qt GUI, se utilizará PyQt5 para la demostración de ejemplos. Aparte de estas dos versiones,

Riverbank Computing también proporciona PyQt3D: los enlaces de Python para el marco Qt3D. Qt3D es un marco de aplicación utilizado para crear sistemas de simulación en tiempo real con renderizado 2D/3D.

Cómo instalar PyQt5

En este tutorial de PyQt5, veremos las dos formas de instalar PyQt:

  • Usando archivos de rueda
  • Construyendo e instalando desde la fuente

Qt (pronunciado lindo) es un sistema complejo y la base de código PyQt contiene código compilado. C++ y el Python código subyacente. Como resultado, es un proceso complicado compilarlo e instalarlo desde la fuente en comparación con otras bibliotecas de Python. Sin embargo, puedes instalar PyQt5 fácilmente usando wheels.

Instalación con ruedas

Las ruedas son el nuevo estándar Python Formato de embalaje y distribución. En términos simples, una rueda es un archivo ZIP con un nombre especial y .whl extensión de archivo. Las ruedas se pueden instalar usando pip (Python's administrador de paquetes), que se incluye de forma predeterminada en las versiones recientes de Python.

Entonces, si tienes Python 3.4 o posterior instalado, ya tienes pip. Sin embargo, si estás usando una versión anterior de Python, debes descargar e instalar pip antes de continuar. Puede buscar instrucciones para ello en este enlace: https://pypi.org/project/pip/.

Para instalar PyQt5,

Paso 1) Abra el símbolo del sistema.
Abra el símbolo del sistema o PowerShell en su Windows maquina

instalar PyQt5

Paso 2) Escriba lo siguiente.

 pip install PyQt5

Paso 3) Instalación exitosa.
Este paso de este tutorial de PyQt5 descargará el paquete whl de PyQt5 (aproximadamente 50 MB) y lo instalará en su sistema.

instalar PyQt5

Alternativamente, también puedes descargar un Windows binario para la versión de Python instalada en su computadora.

Una vez que esté completo, continúe con la siguiente sección de este tutorial de PyQt5 para escribir su primera aplicación GUI.

PyQt básico Concepts y Programas

Ahora que ha instalado correctamente PyQt5 en su computadora, está listo para escribir Python Aplicaciones de diseño de GUI.

Comencemos con una aplicación simple en este tutorial de PyQt5 que mostrará una ventana vacía en su pantalla.

Enciende tu pitón IDLE y escribe lo siguiente:

Programa 1

import sys
from PyQt5.QtWidgets import QApplication, QWidget
if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = QWidget()
    w.resize(300,300)
    w.setWindowTitle("Guru99")
    w.show()
    sys.exit(app.exec_())

Guárdelo como app.py (el nombre no importa) y presione F5 para ejecutar el programa. Alternativamente, simplemente haga doble clic en el archivo guardado para iniciar la aplicación. Si ha hecho todo correctamente, se abrirá una nueva ventana con el título Guru99 como se muestra a continuación.

PyQt básico Concepts

¡Excelente! Esta funcionando. No es mucho, pero es suficiente para entender lo básico. Ahora, en este tutorial de PyQt, veamos en detalle qué hace cada una de las líneas de su programa.

from PyQt5.QtWidgets import QApplication, QWidget

Esta declaración importa todos los módulos que necesita para crear una GUI en el espacio de nombres actual. El módulo QtWidgets contiene todos los widgets principales que utilizará en este Python Tutorial de Qt.

app = QApplication(sys.argv)

Aquí, está creando un objeto de la clase QApplication. Este paso es una necesidad para PyQt5; Cada aplicación de UI debe crear una instancia de QApplication, como una especie de punto de entrada a la aplicación. Si no lo crea, se mostrarán errores.

sys.argv es la lista de parámetros de línea de comandos que puede pasar a la aplicación cuando la inicia a través del shell o mientras automatiza la interfaz.

En este ejemplo de PyQt5, no pasó ningún argumento a QApplications. Por lo tanto, también puedes reemplazarlo con el código siguiente y ni siquiera tener que importar el módulo sys.

app = QApplication([])
w = QWidget()

A continuación, creamos un objeto de la clase QWidget. QWidget es la clase base de todos los objetos UI en Qt, y prácticamente todo lo que ves en una aplicación es un widget. Eso incluye cuadros de diálogo, textos, botones, barras, etc. La característica que te permite diseñar interfaces de usuario complejas es que los widgets se pueden anidar, es decir, puedes tener un widget dentro de un widget, que a su vez está dentro de otro widget. Verás esto en acción en la siguiente sección.

w.resize(300,300)

El método de cambio de tamaño de la clase QWidget le permite configurar las dimensiones de cualquier widget. En este caso, ha cambiado el tamaño de la ventana a 300 px por 300 px.

Aquí, debes recordar que los widgets se pueden anidar juntos; el widget más externo (es decir, el widget sin padre) se llama Ventana.

w.setWindowTitle("Guru99")

El método setWindowTitle() le permite pasar una cadena como argumento que establecerá el título de la ventana según la cadena que pase. En el ejemplo de PyQt5, la barra de título mostrará Guru99.

w.show()

show() simplemente muestra el widget en la pantalla del monitor.

sys.exit(app.exec_())

El método app.exec_() inicia Qt/C++ bucle de eventos. Como sabes, PyQt está escrito en gran medida en C++ y utiliza el mecanismo de bucle de eventos para implementar la ejecución paralela. app.exec_() pasa el control a Qt, que saldrá de la aplicación solo cuando el usuario la cierre desde la GUI. Es por eso que Ctrl+C no saldrá de la aplicación como en otros programas de Python. Dado que Qt tiene control sobre la aplicación, los eventos de Python no se procesan a menos que los configuremos dentro de la aplicación. Además, tenga en cuenta que el método exec tiene un guión bajo en su nombre; esto se debe a que exec() ya era una palabra clave en Python y el guión bajo resuelve el conflicto de nombres.

Más allá de las ventanas vacías

En la sección anterior, viste cómo crear un widget básico en Qt. Ahora es el momento de crear interfaces más complejas con las que los usuarios realmente puedan interactuar. De nuevo, enciende tu IDLE y escribe lo siguiente.

import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QMessageBox

def dialog():
    mbox = QMessageBox()

    mbox.setText("Your allegiance has been noted")
    mbox.setDetailedText("You are now a disciple and subject of the all-knowing Guru")
    mbox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
            
    mbox.exec_()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = QWidget()
    w.resize(300,300)
    w.setWindowTitle("Guru99")
    
    label = QLabel(w)
    label.setText("Behold the Guru, Guru99")
    label.move(100,130)
    label.show()

    btn = QPushButton(w)
    btn.setText('Beheld')
    btn.move(110,150)
    btn.show()
    btn.clicked.connect(dialog)

    
    w.show()
    sys.exit(app.exec_())

Guarde el archivo como appone.py o como desee y presione F5 para ejecutar el programa. Si no ha cometido ningún error, el IDLE Se abrirá una nueva ventana con algo de texto y un botón como se muestra a continuación.

Más allá del vacío Windows

  1. Una vez que haga clic en el botón en la primera ventana, se abrirá un nuevo cuadro de mensaje con el texto que había escrito.
  2. Ahora puede hacer clic en el botón Ocultar detalles/Mostrar detalles para alternar la visibilidad de texto adicional.

Como puedes ver, como no habíamos establecido ningún título de ventana en el cuadro de mensaje, Python proporcionó un título predeterminado.

Ahora que está funcionando, echemos un vistazo al código adicional que agregó al ejemplo anterior de PyQt5.

from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QMessageBox

Esto importa algunos widgets más que ha utilizado en los ejemplos de PyQt5, a saber, QLabel, QPushButton y QMessage.Box.

def dialog():
    mbox = QMessageBox()

    mbox.setText("Your allegiance has been noted")
    mbox.setDetailedText("You are now a disciple and subject of the all-knowing Guru")
    mbox.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
            
    mbox.exec_()

Aquí, ha definido un método llamado diálogo que crea un widget de cuadro de mensaje y establece algún texto en los botones y otros campos.

El método de diálogo se llama desde el bloque principal del programa cuando se presiona un botón en un widget específico (en este caso, el btn PushButton). El evento de clic activado en ese botón hace que se ejecute esta función. Esta función se llama ranura en Qt y aprenderá más sobre señales y el ranuras en los próximos párrafos.

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = QWidget()
    w.resize(300,300)
    w.setWindowTitle("Guru99")

Esta es la sección principal de la aplicación y, como en el ejemplo anterior, comienza creando una instancia de QApplication seguida de un widget simple, es decir, una instancia de QWidget.

label = QLabel(w)
    btn = QPushButton(w)

Ha agregado dos nuevos widgets en esta aplicación: QLabel y QPushButton. QLabel se usa para imprimir texto no editable o marcadores de posición dentro de un widget, mientras que QPushButton se usa para crear un botón en el que se puede hacer clic.

Lo fundamental a tener en cuenta aquí es que cuando crea los objetos etiqueta y btn, está pasando el objeto de ventana (w) a los constructores de QLabel y QPushButton. Así es como funciona el anidamiento en PyQt5. Para crear un widget dentro de otro widget, pasa la referencia del widget principal al constructor del hijo.

label.move(100,130)
btn.move(110,150)

move() se utiliza para establecer la posición de un widget con respecto a su widget principal. En el primer caso, la etiqueta se moverá 100 px desde la izquierda y 130 px desde la parte superior de la ventana.

De manera similar, el botón se colocará a 110 px desde la izquierda y a 150 px desde la parte superior de la ventana. Este ejemplo es una forma tosca de lograr diseños y generalmente no se utiliza en producción; solo se incluye aquí con fines de aprendizaje. Qt admite diferentes diseños que verá en detalle en las próximas secciones de este tutorial de PyQt.

btn.clicked.connect(dialog)

Finalmente, este es un ejemplo de señales y ranuras en Qt. En las aplicaciones basadas en GUI, las funciones se ejecutan en función de las acciones realizadas por el usuario, como pasar el cursor sobre un elemento o hacer clic en un botón. Estas acciones se llaman eventos. Recuerde que el método app.exec_() transfiere el control al Qt Evento-bucle. Para eso está el bucle de eventos: escuchar eventos y realizar acciones en respuesta.

Cada vez que ocurre un evento, como un usuario que hace clic en un botón, el widget Qt correspondiente genera un señal. Estas señales se pueden conectar a funciones de python (como la función de diálogo en este ejemplo) para que la función se ejecute cuando se active una señal. Estas funciones se llaman ranuras en la jerga Qt.

Posteriormente, la sintaxis básica para activar una función de ranura en respuesta a la señal de un evento es la siguiente

 widget.signal.connect(slot)

Lo que significa que siempre que un señal es provocado por un Reproductor, el conectado slot se ejecutará la función. En resumen, Qt utiliza señales y ranuras para comunicarse entre objetos y facilitar la reutilización y la interactividad de los componentes.

Ahora que sabe cómo anidar widgets e implementar interacciones usando señales y ranuras, aquí hay una lista de widgets útiles y otras clases que puede usar en sus aplicaciones PyQt.

Componentes y widgets

Hay una gran cantidad de widgets disponibles en PyQt para crear aplicaciones GUI. Sin embargo, con PyQt5, ha habido una reorganización de clases en diferentes módulos y revisiones en las licencias.

Por lo tanto, es fundamental tener una visión de alto nivel de la estructura de PyQt5. En esta sección, verá cómo se organiza internamente PyQt5 y conocerá los diferentes módulos, bibliotecas y clases API proporcionadas por PyQt5.

Estructura del directorio PyQt5

Estructura del directorio PyQt5

Estos son los módulos fundamentales utilizados por PythonEnlace Qt, específicamente PyQt5.

  • Qt: Combina todas las clases/módulos mencionados a continuación en un solo módulo. Aumenta considerablemente la memoria utilizada por la aplicación. Sin embargo, es más fácil administrar el marco importando solo un módulo.
  • QtCore: Contiene las clases principales no gráficas utilizadas por otros módulos. Aquí es donde se implementan el bucle de eventos, las señales y la conectividad de ranuras de Qt, etc.
  • QtWidgets: Contiene la mayoría de los widgets disponibles en Pyqt5.
  • QtGui: Contiene componentes GUI y amplía el módulo QtCore.
  • Red Qt: Contiene clases utilizadas para implementar la programación de red a través de Qt. Admite servidores TCP, sockets TCP, sockets UDP, manejo de SSL, sesiones de red y búsquedas de DNS.
  • Multimedia Qt proporciona funcionalidad multimedia de bajo nivel.
  • qtsql: implementa la integración de bases de datos para bases de datos SQL. Admite ODBC, MySQL, Oracle, SQLitey PostgreSQL.

Widgets de PyQt5

Aquí hay una lista de los widgets más utilizados en PyQt5.

  • QLineEditar: Este es un campo de entrada que permite al usuario ingresar una línea de texto.
    line = QLineEdit()
  • Botón QRadio: Este es un campo de entrada con un botón seleccionable, similar a los botones de opción en HTML.
    rad = QRadioButton("button title")
    rad.setChecked(True)  #to select the button by default.
  • QComboBox: Se utiliza para mostrar un menú desplegable con una lista de elementos seleccionables.
    drop = QComboBox(w)
    drop.addItems(["item one", "item two", "item three"])
  • QComprobarBox:Muestra un cuadro cuadrado seleccionable delante de la etiqueta que se marca si se selecciona, similar a los botones de opción.
    check = QCheckBox("button title")
  • QMenúBar: muestra una barra de menú horizontal en la parte superior de una ventana. Sólo puedes agregar objetos de la clase QMenu a esta barra. Esos objetos QMenu pueden contener además cadenas, objetos QAction u otros objetos QMenu.
  • Barra de herramientas Q: Es una barra o panel horizontal que se puede mover dentro de la ventana. Puede contener botones y otros widgets.
  • QTab: se utiliza para dividir el contenido de una ventana en varias páginas a las que se puede acceder a través de diferentes pestañas en la parte superior del widget. Consta de dos secciones: la barra de pestañas y la página de pestañas.
  • Barra de desplazamiento Q: Se utiliza para crear barras de desplazamiento que permiten al usuario desplazarse hacia arriba y hacia abajo dentro de una ventana. Consiste en un control deslizante móvil, una pista deslizante y dos botones para desplazar el control deslizante hacia arriba o hacia abajo.
    scroll = QScrollBar()
  • divisor Q: Los divisores se utilizan para separar el contenido de una ventana de modo que los widgets estén agrupados correctamente y no parezcan desordenados. QSplitter es uno de los principales controladores de diseño disponibles en PyQt5 y se utiliza para dividir el contenido tanto horizontal como verticalmente.
  • QDock: Un widget de acoplamiento es una subventana con dos propiedades:
  • Se puede mover dentro de la ventana principal y
  • Se puede acoplar fuera de la ventana principal a otra ubicación de la pantalla.

Diseños y temas

En los ejemplos anteriores de PyQt5, solo has estado usando los métodos move() y resize() para establecer las posiciones de los widgets en tu GUI.

Sin embargo, PyQt tiene un potente motor de gestión de diseño que se puede utilizar para crear interfaces de usuario avanzadas para aplicaciones. En esta sección, aprenderá sobre dos clases importantes que se utilizan en Qt para crear y administrar diseños.

  1. QBoxDisposición
  2. Diseño QGrid

QBoxDisposición

QBoxEl diseño se utiliza para alinear los widgets secundarios del diseño en una fila horizontal o vertical. Las dos clases de interés que heredan de QBoxEl diseño es:

  • QHBoxDiseño: se utiliza para alinear los widgets secundarios horizontalmente.
  • QVBoxDiseño: se utiliza para alinear los widgets secundarios verticalmente.

Por ejemplo, así se alinean tres botones con QHBoxSe verá el diseño.

QBoxDisposición

import sys
from PyQt5.QtWidgets import *

if __name__ == "__main__":

    app = QApplication([])
    w = QWidget()
    w.setWindowTitle("Musketeers")

    btn1 = QPushButton("Athos")
    btn2 = QPushButton("Porthos")
    btn3 = QPushButton("Aramis")

    hbox = QHBoxLayout(w)

    hbox.addWidget(btn1)
    hbox.addWidget(btn2)
    hbox.addWidget(btn3)

    w.show()

    sys.exit(app.exec_())

Y así quedarán en QVBoxDiseño.

QBoxDisposición

import sys
from PyQt5.QtWidgets import *

if __name__ == "__main__":

    app = QApplication([])
    w = QWidget()
    w.setWindowTitle("Musketeers")

    btn1 = QPushButton("Athos")
    btn2 = QPushButton("Porthos")
    btn3 = QPushButton("Aramis")

    vb = QVBoxLayout(w)

    vb.addWidget(btn1)
    vb.addWidget(btn2)
    vb.addWidget(btn3)

    w.show()

    sys.exit(app.exec_())

La única función que necesita explicación en este momento es el método addWidget(). Se utiliza para insertar widgets en el HBox o VBox disposición. También se utiliza en otros diseños donde requiere una cantidad diferente de parámetros, como verá en la siguiente sección. Los widgets aparecerán dentro del diseño en el orden en que los inserte.

Diseño QGrid

QGridLayout se utiliza para crear interfaces en las que los widgets se disponen en forma de cuadrícula (como una matriz o una matriz 2D). Para insertar elementos en un diseño de cuadrícula, puede utilizar la representación matricial para definir el número de filas y columnas en la cuadrícula, así como la posición de esos elementos.

Por ejemplo, para crear una cuadrícula de 3*3 (es decir, una cuadrícula con tres filas y tres columnas), escribirá el siguiente código:

Import sys
from PyQt5.QtWidgets import *

if __name__ == "__main__":
    app = QApplication([])

    w = QWidget()

    grid = QGridLayout(w)

    for i in range(3):
        for j in range(3):
            grid.addWidget(QPushButton("Button"),i,j)


    w.show()
    sys.exit(app.exec_())

Esta será la salida:

Diseño QGrid

El método addWidget() en el diseño de la cuadrícula toma estos argumentos:

  • El objeto widget que desea agregar a la cuadrícula
  • La coordenada x del objeto.
  • La coordenada y del objeto.
  • El intervalo de filas (predeterminado = 0)
  • El intervalo de columnas (predeterminado = 0)

Para entenderlo mejor, puede insertar manualmente cada widget como se muestra a continuación.

import sys
from PyQt5.QtWidgets import *

if __name__ == "__main__":
    app = QApplication([])

    w = QWidget()

    grid = QGridLayout(w)
    grid.addWidget(QPushButton("Button one"),0,0)
    grid.addWidget(QPushButton("Button two"),0,1)
    grid.addWidget(QPushButton("Button three"),1,0)
    grid.addWidget(QPushButton("Button four"),1,1)


    w.show()
    sys.exit(app.exec_())

Así es como se verá la cuadrícula:

Diseño QGrid

También puede pasar los parámetros rowspan y colspan a addWidget() para abarcar más de una fila o columna.

Por ejemplo,

grid.addWidget(QPushButton("Button five"),2,0,1,0)

Esto creará un botón que se extenderá sobre ambas columnas.

Diseño QGrid

Temáticas

PyQt5 viene con algunos temas integrados que puedes usar en tus aplicaciones. El setStyle () El método llamado en la instancia de QApplication se utiliza para establecer un tema particular para su aplicación.

Por ejemplo, agregar la siguiente línea de código cambiará el tema de su aplicación del predeterminado a Fusion

app.setStyle("Fusion")

Así se verá el ejemplo anterior en Fusion Theme

Temáticas

Otra función útil para tematizar tus aplicaciones es el método setPalette(). Aquí está el código para cambiar el color de diferentes widgets usando setPalette().

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import *
from PyQt5.QtGui import QPalette

if __name__ == "__main__":
    app = QApplication([])
    app.setStyle("Fusion")
    
    qp = QPalette()
    qp.setColor(QPalette.ButtonText, Qt.black)
    qp.setColor(QPalette.Window, Qt.black)
    qp.setColor(QPalette.Button, Qt.gray)
    app.setPalette(qp)

    w = QWidget()

    grid = QGridLayout(w)
    grid.addWidget(QPushButton("Button one"),0,0)
    grid.addWidget(QPushButton("Button two"),0,1)
    grid.addWidget(QPushButton("Button three"),1,0)
    grid.addWidget(QPushButton("Button four"),1,1)


    w.show()
    sys.exit(app.exec_())

Aquí está el resultado.

Temáticas

Para utilizar el método setPalette(), primero debe definir una paleta. Esto se hace creando un objeto de la clase QPalette.

 qp = QPalette()

Tenga en cuenta que la clase QPalette pertenece al módulo QtGui y deberá importarla para que esto funcione. Una vez que haya creado el objeto QPalette, use el método setColor() para pasar el nombre de un widget cuyo color desea cambiar y el color que desea configurar.

 qp.setColor(QPalette.Window, Qt.black)

Esto cambiará el color de la ventana a negro. Después de haber definido su combinación de colores, use la función setPalette() para aplicar la paleta a su aplicación.

app.setPalette(qp)

Eso es todo lo que necesitas hacer si quieres crear algunos temas básicos para tu aplicación. PyQt también te permite usar hojas de estilo para definir el aspecto de tus widgets. Si está familiarizado con CSS, puede definir fácilmente estilos avanzados para su aplicación utilizando las hojas de estilo Qt.

Resum

  • PyQt es el enlace de Python para C++ Marco de interfaz de usuario, Qt.
  • PyQt4 y PyQt5 son las dos versiones principales desarrolladas por Riverbank Computing.
  • Los principales módulos del marco PyQt son:
    1. Qt
    2. QtCore
    3. QtWidgets
    4. QtGui
    5. qtsql
    6. Red Qt
  • PyQt admite varios widgets como:
    1. Botones
    2. Etiquetas de texto
    3. Campos de texto
    4. Botones de opción y casillas de verificación
    5. Barras de herramientas y barras de menú
    6. webkit
    7. Pestañas
    8. Docks
  • En PyQt, la interactividad se implementa utilizando señales y el ranuras.
  • An evento es una acción realizada por un usuario en la GUI (como hacer clic en un botón).
  • A señal es generado por el widget correspondiente cuando ocurre un evento en él.
  • A slot es una función que está conectada a la señal y se ejecuta cuando se eleva la señal.
  • PyQt tiene un motor de diseño robusto y admite gestión y diseño de diseño avanzado. Estos son dos esquemas de diseño de uso frecuente en PyQt:
    1. Box Disposición
    2. diseño de cuadrícula
  • El diseñador PyQt le permite crear temas personalizados para aplicaciones GUI y tiene soporte incorporado para hojas de estilo.
  • creador de qt Python se puede utilizar para crear interfaces de usuario y aplicaciones independientes.