¿Cómo instalar PyQt?

PyQt: Creando Aplicaciones de Escritorio con Python

10/12/2023

Valoración: 4.85 (6638 votos)

En el vasto universo de la programación, la capacidad de crear interfaces gráficas de usuario (GUI) intuitivas y funcionales es fundamental para el éxito de cualquier aplicación. Si eres un desarrollador Python y buscas construir herramientas de escritorio potentes y visualmente atractivas, PyQt es, sin duda, una de las opciones más destacadas. PyQt es un kit de herramientas de widgets GUI que actúa como una interfaz de Python para Qt, una de las bibliotecas GUI multiplataforma más robustas y populares del mundo. Desarrollado por RiverBank Computing Ltd., PyQt permite a los desarrolladores aprovechar toda la potencia de Qt directamente desde sus scripts de Python.

¿Cómo instalar PyQt?
Para PyQt, la instalación es más fácil que quitarle un caramelo a un bebé. Todo lo que tienes que hacer es obtener un enlace para descargar, instalar el paquete descargado y estar usando la aplicación antes de que te des cuenta. Para wxPython, la instalación en Linux y Windows es fácil, pero muy agitada en Mac OS. El diseño de PyQt es muy sencillo.

Este artículo te guiará a través de los aspectos esenciales de PyQt, desde su instalación hasta la creación de aplicaciones complejas, pasando por la gestión de eventos, el uso de herramientas de diseño y la integración con bases de datos. Prepárate para transformar tus ideas en programas de escritorio con una interfaz de usuario profesional.

Índice de Contenido

¿Cómo Instalar PyQt?

La instalación de PyQt es un proceso sencillo, especialmente para los usuarios de Windows que utilizan Python 3.5 o posterior. La forma más recomendada y eficiente es a través del gestor de paquetes PIP (Python Package Installer).

Instalación en Windows

Para instalar la última versión estable de PyQt5, abre tu terminal o línea de comandos y ejecuta el siguiente comando:

pip3 install PyQt5

Este comando descargará e instalará los paquetes necesarios para PyQt5, compatibles con arquitecturas de 32 o 64 bits. Para aquellos que deseen utilizar herramientas de desarrollo adicionales como Qt Designer (una herramienta visual para diseñar interfaces de usuario), se recomienda instalar también el paquete pyqt5-tools:

pip3 install pyqt5-tools

Instalación en Linux / macOS

Aunque PIP es la forma preferida para Windows, en sistemas operativos como Linux o macOS, también tienes la opción de compilar PyQt5 desde el código fuente. Esta opción, aunque más compleja, ofrece mayor flexibilidad y control sobre la instalación. Puedes encontrar los archivos fuente y las instrucciones detalladas en el sitio web oficial de RiverBank Computing.

Explorando la API de PyQt: Módulos Esenciales

La API de PyQt es una vasta colección de módulos, clases y funciones que proporcionan una amplia gama de funcionalidades. Cada módulo está diseñado para un propósito específico, lo que permite una organización y una gestión eficientes de las distintas características de la aplicación. A continuación, se detallan algunos de los módulos más utilizados:

No.MóduloDescripción
1QtCoreClases principales no GUI utilizadas por otros módulos para funcionalidad básica.
2QtGuiComponentes de la interfaz gráfica de usuario, incluyendo clases para dibujar, fuentes e imágenes.
3QtWidgetsClases para crear interfaces de usuario clásicas de escritorio, incluyendo la mayoría de los widgets.
4QtMultimediaClases de programación multimedia de bajo nivel.
5QtNetworkClases para programación en red.
6QtOpenGLClases de soporte para OpenGL.
7QtScriptClases para evaluar scripts de Qt.
8QtSqlClases para integración de bases de datos usando SQL.
9QtSvgClases para mostrar el contenido de archivos SVG.
10QtWebKitClases para renderizar y editar HTML (en PyQt5, esto se ha movido a QtWebEngine).
11QtXmlClases para el manejo de XML.
12QtDesignerClases para extender Qt Designer.
13QtAssistantSoporte para ayuda en línea.

Principales Diferencias entre PyQt4 y PyQt5

Es importante señalar que la API de PyQt5 no es automáticamente compatible con versiones anteriores de PyQt4. Si estás migrando código, deberás realizar cambios manuales. Aquí te presentamos algunas de las diferencias más significativas:

  • PyQt5 no es compatible con versiones de Python anteriores a la v2.6.
  • El método connect() de la clase QObject para la conexión entre señal y slot ha cambiado. La sintaxis anterior QObject.connect(widget, QtCore.SIGNAL('signalname'), slot_function) ya no se utiliza. La nueva sintaxis es widget.signal.connect(slot_function).
  • Las clases definidas previamente en el módulo QtGui se han redistribuido entre QtGui, QtPrintSupport y QtWidgets. Esto significa que muchos widgets que antes importabas de QtGui, ahora los importarás de QtWidgets.
  • En la clase QFileDialog, los métodos getOpenFileNameAndFilter(), getOpenFileNamesAndFilter() y getSaveFileNameAndFilter() han sido reemplazados por getOpenFileName(), getOpenFileNames() y getSaveFileName(), respectivamente.
  • PyQt5 no tiene disposición para definir una clase que sea subclase de más de una clase Qt.
  • Las utilidades pyuic5 y pyrcc5 han simplificado sus opciones, eliminando flags específicos de versiones de Python.
  • PyQt5 invoca automáticamente sip.setdestroyonexit(), asegurando que los destructores C++ de las instancias envueltas se llamen al salir.

Creando Tu Primera Aplicación GUI en PyQt: "Hola Mundo"

Crear una aplicación GUI simple en PyQt es un excelente punto de partida para entender su funcionamiento. Aquí te mostramos cómo hacerlo con un ejemplo clásico de "Hola Mundo", tanto en un estilo procedural como en uno orientado a objetos.

Enfoque Procedural

Los pasos básicos para una aplicación simple son:

  1. Importar los módulos necesarios de PyQt5 (QtCore, QtGui, QtWidgets).
  2. Crear una instancia de QApplication, que gestiona el bucle de eventos de la aplicación.
  3. Crear un objeto QWidget, que servirá como la ventana principal.
  4. Añadir un widget como QLabel para mostrar texto.
  5. Establecer el texto de la etiqueta y configurar la geometría (posición y tamaño) de la ventana.
  6. Mostrar la ventana.
  7. Entrar en el bucle principal de la aplicación con app.exec_() para que la aplicación responda a los eventos.

Aquí tienes el código:

import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel def window(): app = QApplication(sys.argv) w = QWidget() b = QLabel(w) b.setText("Hello World!") w.setGeometry(100,100,200,50) b.move(50,20) w.setWindowTitle("PyQt5") w.show() sys.exit(app.exec_()) if __name__ == '__main__': window()

Enfoque Orientado a Objetos

El enfoque orientado a objetos es el más recomendado para aplicaciones GUI, ya que permite una mejor organización y escalabilidad del código. Aquí, la ventana principal se define como una clase que hereda de QWidget.

import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel from PyQt5.QtGui import QFont class Window(QWidget): def __init__(self, parent = None): super(Window, self).__init__(parent) self.resize(200,50) self.setWindowTitle("PyQt5") self.label = QLabel(self) self.label.setText("Hello World") font = QFont() font.setFamily("Arial") font.setPointSize(16) self.label.setFont(font) self.label.move(50,20) def main(): app = QApplication(sys.argv) ex = Window() ex.show() sys.exit(app.exec_()) if __name__ == '__main__': main()

Ambos códigos producirán una pequeña ventana con el texto "Hello World!" centrado.

Herramientas de Desarrollo PyQt5

PyQt5 no solo proporciona la biblioteca en sí, sino también un conjunto de utilidades que facilitan enormemente el proceso de desarrollo. Estas herramientas son esenciales para diseñar, traducir y compilar recursos de tu aplicación.

No.HerramientaDescripción
1assistantHerramienta de documentación Qt Assistant, útil para consultar la API.
2pyqt5designerLa herramienta de diseño de GUI de Qt Designer, una interfaz visual de arrastrar y soltar.
3linguistHerramienta de traducción Qt Linguist, para localizar tu aplicación.
4lreleaseCompila archivos .ts (traducción) en archivos .qm (ejecutables).
5pylupdate5Extrae cadenas de traducción y genera o actualiza archivos .ts.
6qmakeHerramienta de construcción de software Qt.
7pyqt5qmlsceneVisor de archivos QML.
8pyqmlviewerOtro visor de archivos QML.
9pyrcc5Compilador de archivos de recursos Qt, para incrustar recursos como imágenes.
10pyuic5Compilador de interfaz de usuario Qt para generar código Python a partir de archivos .ui.
11pyqmltestrunnerEjecuta pruebas unitarias en código QML.
12qdbusHerramienta de línea de comandos para enumerar servicios D-Bus.
13QDocGenerador de documentación para proyectos de software.
14QhelpgeneratorGenera y visualiza archivos de ayuda de Qt.
15qmlimportscannerAnaliza e informa sobre importaciones QML.

Jerarquía de Clases y Widgets Comúnmente Usados

La API de PyQt se construye sobre una jerarquía de clases bien definida, siendo QObject la clase base para todos los objetos Qt. QPaintDevice es la clase base para cualquier objeto que pueda ser pintado. La clase QApplication es el corazón de cualquier aplicación GUI, gestionando la configuración principal y el bucle de eventos.

La clase QWidget, derivada de QObject y QPaintDevice, es la clase base para todos los objetos de la interfaz de usuario. A partir de QWidget, se derivan otras clases fundamentales como QDialog y QMainWindow, que forman la base de las ventanas de tu aplicación.

Widgets de Uso Frecuente

PyQt ofrece una rica colección de widgets, cada uno con una funcionalidad específica. Aquí una lista selecta de los más utilizados:

No.WidgetDescripción
1QLabelSe usa para mostrar texto no editable o imágenes.
2QLineEditPermite al usuario ingresar una línea de texto.
3QTextEditPermite al usuario ingresar texto de varias líneas.
4QPushButtonUn botón de comando para invocar una acción.
5QRadioButtonPermite elegir una opción entre varias.
6QCheckBoxPermite elegir entre una o más opciones.
7QSpinBoxPermite aumentar/disminuir un valor entero.
8QScrollBarPermite acceder al contenido de un widget más allá de la pantalla visible.
9QSliderPermite cambiar un valor límite linealmente.
10QComboBoxProporciona una lista desplegable de elementos para seleccionar.
11QMenuBarBarra horizontal que contiene objetos QMenu.
12QStatusBarGeneralmente en la parte inferior de QMainWindow, proporciona información de estado.
13QToolBarGeneralmente en la parte superior de QMainWindow o flotante, contiene botones de acción.
14QListViewProporciona una lista seleccionable de elementos en modo Lista o Icono.
15QPixmapRepresentación de imágenes fuera de pantalla para mostrarlas en QLabel o QPushButton.
16QDialogVentana modal o no modal que puede devolver información a la ventana principal.

El Marco QMainWindow

La ventana de nivel superior de una aplicación GUI típica se crea con el objeto QMainWindow. Esta clase proporciona un marco de aplicación que tiene su propia barra de menú, barra de herramientas, barra de estado y un área central de widgets. Algunos widgets ocupan lugares designados en esta ventana principal, mientras que otros se colocan en el área central de widgets utilizando varios administradores de diseño.

¿Cómo crear aplicaciones de escritorio con PyQt?
El primer paso para crear aplicaciones de escritorio con PyQt es hacer que aparezca una ventana en su escritorio, en este artículo veremos cómo podemos cambiar el color de esta ventana. Para cambiar el color de la ventana principal usamos el setStylesheet () método. Argumento: Toma una string como argumento.

Diseñando GUIs con Qt Designer

El instalador de PyQt incluye una herramienta de diseño de GUI llamada Qt Designer. Esta herramienta es invaluable porque permite construir interfaces gráficas de usuario de forma visual, arrastrando y soltando widgets sin necesidad de escribir código a mano. Aunque no es un IDE completo, simplifica enormemente el proceso de diseño.

Proceso de Diseño con Qt Designer

  1. Inicia Qt Designer (generalmente se encuentra en la carpeta Scripts de tu entorno virtual si lo instalaste con pyqt5-tools).
  2. Comienza a diseñar tu interfaz eligiendo Archivo → Nuevo.
  3. Arrastra y suelta los widgets necesarios desde el cuadro de widgets en el panel izquierdo hacia tu formulario.
  4. Puedes asignar valores a las propiedades de los widgets directamente en el panel de propiedades.
  5. Guarda el formulario diseñado como un archivo .ui (por ejemplo, demo.ui). Este archivo contiene una representación XML de tus widgets y sus propiedades.

Convertir Archivos .ui a Código Python

Una vez que tengas tu archivo .ui, puedes traducirlo a código Python utilizando la utilidad de línea de comandos pyuic5. Esta herramienta es un envoltorio para el módulo uic del kit de herramientas Qt.

pyuic5 -x demo.ui -o demo.py

El modificador -x añade un pequeño fragmento de código adicional al script Python generado para que se convierta en una aplicación autocontenida y auto-ejecutable. El archivo demo.py resultante contendrá la estructura de tu interfaz de usuario en código Python, lista para ser utilizada en tu aplicación.

Manejo de Eventos: Señales y Slots

A diferencia de las aplicaciones de consola que se ejecutan de forma secuencial, las aplicaciones GUI están impulsadas por eventos. Esto significa que las funciones o métodos se ejecutan en respuesta a las acciones del usuario, como hacer clic en un botón, seleccionar un elemento o mover el ratón. Estas acciones son llamadas eventos.

Los widgets en PyQt actúan como fuentes de eventos. Cada widget de PyQt, que se deriva de la clase QObject, está diseñado para emitir una señal en respuesta a uno o más eventos. Una señal por sí sola no realiza ninguna acción; en cambio, está 'conectada' a un slot. Un slot puede ser cualquier función invocable de Python.

Conexión de Señales y Slots con Qt Designer

Qt Designer facilita la conexión de señales y slots visualmente:

  1. Diseña un formulario simple con un control QLineEdit y un QPushButton.
  2. Activa el modo de edición de señales/slots (Editar → Editar señales/ranuras o presiona F4).
  3. Arrastra el cursor desde el botón hacia el cuadro de texto.
  4. Al soltar el ratón, aparecerá un cuadro de diálogo que muestra las señales del botón y los métodos de slot del cuadro de texto. Selecciona la señal clicked() del botón y el método clear() del cuadro de texto.
  5. Guarda el archivo .ui y compílalo a Python con pyuic5. El código generado incluirá la conexión: self.pushButton.clicked.connect(self.lineEdit.clear).

Conexión de Señales y Slots por Código

También puedes establecer una conexión de señal/slot directamente en tu código Python utilizando la sintaxis:

widget.signal.connect(slot_function)

Por ejemplo, para conectar el clic de un botón a una función:

import sys from PyQt5.QtWidgets import QApplication, QDialog, QPushButton def window(): app = QApplication(sys.argv) win = QDialog() b1 = QPushButton(win) b1.setText("Botón 1") b1.move(50,20) b1.clicked.connect(b1_clicked) b2 = QPushButton(win) b2.setText("Botón 2") b2.move(50,50) b2.clicked.connect(b2_clicked) win.setGeometry(100,100,200,100) win.setWindowTitle("Ejemplo PyQt5") win.show() sys.exit(app.exec_()) def b1_clicked(): print ("Botón 1 clicado") def b2_clicked(): print ("Botón 2 clicado") if __name__ == '__main__': window()

Este ejemplo demuestra cómo conectar dos botones a funciones Python separadas, imprimiendo un mensaje en la consola cuando se hace clic en cada uno.

Posicionamiento de Widgets y Gestión de Diseños

Inicialmente, podrías pensar en posicionar widgets usando coordenadas absolutas (píxeles) con métodos como setGeometry(xpos, ypos, width, height). Sin embargo, este enfoque tiene varias desventajas:

  • La posición del widget no cambia si se redimensiona la ventana.
  • La apariencia puede no ser uniforme en diferentes dispositivos o resoluciones.
  • Modificar el diseño es difícil, requiriendo a menudo rediseñar todo el formulario.

Para solucionar estos problemas, PyQt proporciona clases de diseño (Layout Managers) que gestionan el posicionamiento de los widgets de forma dinámica y elegante. Las ventajas de los administradores de diseño son:

  • Los widgets dentro de la ventana cambian de tamaño automáticamente al redimensionar la ventana.
  • Se garantiza una apariencia uniforme en diferentes resoluciones de pantalla.
  • Es posible añadir o eliminar widgets dinámicamente sin necesidad de rediseñar.

Clases de Diseño Comunes

No.Clase de DiseñoDescripción
1QBoxLayoutAlinea los widgets vertical u horizontalmente. Sus clases derivadas son QVBoxLayout (vertical) y QHBoxLayout (horizontal).
2QGridLayoutOrganiza los widgets en una cuadrícula de celdas dispuestas en filas y columnas. Permite añadir widgets especificando el número de fila y columna.
3QFormLayoutUna forma conveniente de crear un formulario de dos columnas, donde cada fila consta de una etiqueta y un campo de entrada asociado.

Clases de Diálogo: QDialog y QMessageBox

Las aplicaciones GUI a menudo necesitan interactuar con el usuario a través de ventanas de diálogo para recopilar información o mostrar mensajes importantes. PyQt ofrece clases específicas para esto.

La Clase QDialog

Un widget QDialog presenta una ventana de nivel superior utilizada principalmente para recopilar la respuesta del usuario. Puede configurarse para ser Modal (bloquea la interacción con la ventana principal hasta que se cierra) o Modeless (permite la interacción con otras ventanas mientras está abierta).

PyQt tiene varios widgets de diálogo preconfigurados, como InputDialog, FileDialog, FontDialog, etc. Un diálogo no tiene controles para minimizar y maximizar en su barra de título.

import sys from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QDialog def window(): app = QApplication(sys.argv) w = QWidget() btn = QPushButton(w) btn.setText("Mostrar Diálogo!") btn.move(100,50) btn.clicked.connect(showdialog) w.setWindowTitle("Demo de Diálogo PyQt") w.show() sys.exit(app.exec_()) def showdialog(): dlg = QDialog() b1 = QPushButton("OK", dlg) b1.move(50,50) dlg.setWindowTitle("Diálogo") dlg.setWindowModality(Qt.ApplicationModal) dlg.exec_() if __name__ == '__main__': window()

En este ejemplo, el diálogo es ApplicationModal, lo que significa que el usuario no puede interactuar con la ventana principal hasta que se cierre el diálogo.

La Clase QMessageBox

QMessageBox es un cuadro de diálogo modal de uso común para mostrar mensajes informativos y, opcionalmente, pedir al usuario que responda haciendo clic en cualquiera de los botones estándar. Cada botón estándar tiene un título predefinido, una función y devuelve un número hexadecimal predefinido.

¿Cómo combinar funciones relacionadas con Python y PyQt?
Tenga en cuenta que la funcionalidad por defecto viene con dos botones necesarios, OK y Cancelar. Estos pueden ser modificados haciendo clic en ellos y cambiando su configuración en el Editor de Propiedades. A partir de este punto, puede mezclar y combinar una amplia gama de funciones relacionadas con Python y PyQt.
No.MétodoDescripción
1setIcon()Muestra un icono predefinido (Question, Information, Warning, Critical).
2setText()Establece el texto principal del mensaje.
3setInformativeText()Muestra información adicional.
4setDetailedText()El cuadro de diálogo muestra un botón 'Detalles' para este texto.
5setTitle()Muestra el título personalizado del diálogo.
6setStandardButtons()Lista de botones estándar a mostrar (ej. QMessageBox.Ok | QMessageBox.Cancel).
7setDefaultButton()Establece el botón por defecto (se activa con Enter).
8setEscapeButton()Configura el botón que se activa al presionar Escape.
import sys from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox def window(): app = QApplication(sys.argv) w = QWidget() b = QPushButton(w) b.setText("Mostrar Mensaje!") b.move(100,50) b.clicked.connect(showdialog) w.setWindowTitle("Demo de MessageBox PyQt") w.show() sys.exit(app.exec_()) def showdialog(): msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("Este es un cuadro de mensaje") msg.setInformativeText("Esta es información adicional.") msg.setWindowTitle("Demo de MessageBox") msg.setDetailedText("Los detalles son los siguientes:...") msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel) msg.buttonClicked.connect(msgbtn) retval = msg.exec_() def msgbtn(i): print ("Botón presionado es:", i.text()) if __name__ == '__main__': window()

Interfaces de Documento Múltiple (MDI)

Mientras que los widgets con pestañas o apilados muestran una ventana a la vez, las aplicaciones MDI (Multiple Document Interface) permiten mostrar varias subventanas simultáneamente dentro de un contenedor principal. Esto es útil para aplicaciones que manejan múltiples documentos o vistas al mismo tiempo, como editores de texto o IDEs. El widget contenedor se llama QMdiArea, y las ventanas secundarias son instancias de QMdiSubWindow.

No.Método de QMdiArea/QMdiSubWindowDescripción
1addSubWindow()Añade un widget como una nueva subventana en el área MDI.
2removeSubWindow()Elimina un widget que es un widget interno de una subventana.
3setActiveSubWindow()Activa una subventana.
4cascadeSubWindows()Organiza subventanas en el área MDI en cascada.
5tileSubWindows()Organiza las subventanas en el área MDI en mosaico.
6closeActiveSubWindow()Cierra la subventana activa.
7subWindowList()Devuelve la lista de subventanas en el área MDI.
8setWidget()Establece un QWidget como el widget interno de una instancia de QMdiSubwindow.
import sys from PyQt5.QtCore import * from PyQt5.QtWidgets import QApplication, QMainWindow, QMdiArea, QMdiSubWindow, QTextEdit, QAction class MainWindow(QMainWindow): count = 0 def __init__(self, parent = None): super(MainWindow, self).__init__(parent) self.mdi = QMdiArea() self.setCentralWidget(self.mdi) bar = self.menuBar() file = bar.addMenu("Archivo") file.addAction("Nuevo") file.addAction("Cascada") file.addAction("Mosaico") file.triggered[QAction].connect(self.windowaction) self.setWindowTitle("Demo MDI") def windowaction(self, q): print ("Acción disparada:", q.text()) if q.text() == "Nuevo": MainWindow.count = MainWindow.count+1 sub = QMdiSubWindow() sub.setWidget(QTextEdit()) sub.setWindowTitle("Subventana " + str(MainWindow.count)) self.mdi.addSubWindow(sub) sub.show() elif q.text() == "Cascada": self.mdi.cascadeSubWindows() elif q.text() == "Mosaico": self.mdi.tileSubWindows() def main(): app = QApplication(sys.argv) ex = MainWindow() ex.show() sys.exit(app.exec_()) if __name__ == '__main__': main()

Funcionalidad de Arrastrar y Soltar (Drag and Drop)

La funcionalidad de arrastrar y soltar es muy intuitiva y se encuentra en muchas aplicaciones de escritorio, permitiendo al usuario copiar o mover objetos entre ventanas. La transferencia de datos de arrastrar y soltar basada en MIME se basa en la clase QDrag. Los objetos QMimeData asocian los datos con su tipo MIME correspondiente y se almacenan en el portapapeles para el proceso de arrastrar y soltar.

Método de QMimeDataTipo MIMEDescripción
hasText() / text() / setText()text/plainPara texto sin formato.
hasHtml() / html() / setHtml()text/htmlPara contenido HTML.
hasUrls() / urls() / setUrls()text/uri-listPara listas de URLs.
hasImage() / imageData() / setImageData()image/*Para datos de imagen.
hasColor() / colorData() / setColorData()application/x-colorPara datos de color.

Los widgets que permiten que sus datos sean arrastrados deben tener setDragEnabled(True). Por otro lado, los widgets que deben responder a eventos de arrastrar y soltar implementan métodos para manejar DragEnterEvent (cuando un arrastre entra en el widget), DragMoveEvent (durante el arrastre), DragLeaveEvent (cuando el arrastre sale) y DropEvent (cuando se suelta el objeto).

import sys from PyQt5.QtWidgets import QApplication, QWidget, QComboBox, QLineEdit, QLabel, QFormLayout class Combo(QComboBox): def __init__(self, title, parent): super(Combo, self).__init__(parent) self.setAcceptDrops(True) def dragEnterEvent(self, e): if e.mimeData().hasText(): e.accept() else: e.ignore() def dropEvent(self, e): self.addItem(e.mimeData().text()) class Example(QWidget): def __init__(self): super(Example, self).__init__() self.initUI() def initUI(self): lo = QFormLayout() lo.addRow(QLabel("Escriba texto en el cuadro y arrástrelo al combo box")) edit = QLineEdit() edit.setDragEnabled(True) com = Combo("Button", self) lo.addRow(edit, com) self.setLayout(lo) self.setWindowTitle('Arrastrar y Soltar Simple') def main(): app = QApplication(sys.argv) ex = Example() ex.show() app.exec_() if __name__ == '__main__': main()

Integración de Bases de Datos con QtSql

La biblioteca PyQt5 incluye el módulo QtSql, un sistema de clases para comunicarse con diversas bases de datos SQL. Su clase QSqlDatabase proporciona acceso a través de un objeto de conexión. Esto permite que tu aplicación interactúe con bases de datos como SQLite, MySQL, PostgreSQL, Oracle y más.

No.Método de QSqlDatabaseDescripción
1setDatabaseName()Establece el nombre de la base de datos para la conexión.
2setHostName()Establece el nombre del host donde está instalada la base de datos.
3setUserName()Especifica el nombre de usuario para la conexión.
4setPassword()Establece la contraseña del objeto de conexión.
5commit()Confirma las transacciones.
6rollback()Revierte la transacción de la base de datos.
7close()Cierra la conexión.

La clase QSqlQuery tiene la funcionalidad para ejecutar y manipular comandos SQL (DDL y DML). El método clave es exec_(), que toma una cadena SQL como argumento.

import sys from PyQt5.QtSql import QSqlDatabase, QSqlQuery from PyQt5.QtWidgets import QApplication, QMessageBox def createDB(): db = QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName('sportsdatabase.db') if not db.open(): msg = QMessageBox() msg.setIcon(QMessageBox.Critical) msg.setText("Error al crear la base de datos") retval = msg.exec_() return False query = QSqlQuery() query.exec_("create table sportsmen( id int primary key, ""firstname varchar(20), lastname varchar(20))") query.exec_("insert into sportsmen values(101, 'Roger', 'Federer')") query.exec_("insert into sportsmen values(102, 'Christiano', 'Ronaldo')") query.exec_("insert into sportsmen values(103, 'Ussain', 'Bolt')") query.exec_("insert into sportsmen values(104, 'Sachin', 'Tendulkar')") query.exec_("insert into sportsmen values(105, 'Saina', 'Nehwal')") return True if __name__ == '__main__': app = QApplication(sys.argv) createDB()

Modelos de Tabla y Vistas (QSqlTableModel y QTableView)

Para mostrar datos de una base de datos en una GUI, PyQt utiliza el marco Modelo/Vista. QSqlTableModel proporciona un modelo de datos editable para leer y escribir registros en una sola tabla, y QTableView es un widget que muestra estos datos en una vista desplazable y editable.

import sys from PyQt5.QtSql import QSqlDatabase, QSqlTableModel from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QApplication, QTableView, QDialog, QVBoxLayout, QPushButton def initializeModel(model): model.setTable('sportsmen') model.setEditStrategy(QSqlTableModel.OnFieldChange) model.select() model.setHeaderData(0, Qt.Horizontal, "ID") model.setHeaderData(1, Qt.Horizontal, "Nombre") model.setHeaderData(2, Qt.Horizontal, "Apellido") def createView(title, model): view = QTableView() view.setModel(model) view.setWindowTitle(title) return view def addrow(): print (model.rowCount()) ret = model.insertRows(model.rowCount(), 1) print (ret) def findrow(i): global delrow delrow = i.row() if __name__ == '__main__': app = QApplication(sys.argv) db = QSqlDatabase.addDatabase('QSQLITE') db.setDatabaseName('sportsdatabase.db') # Asegúrate de que la base de datos exista y esté creada createDB() # Llama a la función para crear la DB si no existe model = QSqlTableModel() delrow = -1 initializeModel(model) view1 = createView("Modelo de Tabla (Vista 1)", model) view1.clicked.connect(findrow) dlg = QDialog() layout = QVBoxLayout() layout.addWidget(view1) button = QPushButton("Añadir Fila") button.clicked.connect(addrow) layout.addWidget(button) btn1 = QPushButton("Eliminar Fila") btn1.clicked.connect(lambda: model.removeRow(view1.currentIndex().row())) layout.addWidget(btn1) dlg.setLayout(layout) dlg.setWindowTitle("Demo de Base de Datos") dlg.show() sys.exit(app.exec_())

Pintura y Gráficos con QPainter

Todas las clases QWidget en PyQt son subclases de QPaintDevice, lo que significa que pueden ser dibujadas. La clase QPainter es la herramienta principal para realizar dibujos de bajo nivel en widgets y otros dispositivos pintables. Se utiliza típicamente dentro del método paintEvent() de un widget, que se invoca cada vez que la apariencia del widget necesita ser actualizada.

No.Método de QPainterDescripción
1begin() / end()Inicia/finaliza la pintura en el dispositivo de destino.
2drawArc()Dibuja un arco.
3drawEllipse()Dibuja una elipse.
4drawLine()Dibuja una línea.
5drawPixmap()Dibuja un mapa de píxeles (imagen).
6drawPolygon()Dibuja un polígono.
7drawRect()Dibuja un rectángulo.
8drawText()Muestra texto en coordenadas dadas.
9fillRect()Rellena un rectángulo con un color o patrón.
10setBrush()Establece el estilo de pincel para rellenar formas.
11setPen()Establece el color, tamaño y estilo de la pluma para dibujar contornos.

PyQt también define constantes para estilos de pincel y colores predefinidos, facilitando la personalización visual.

Constantes de Estilo de Pincel

  • Qt.NoBrush: Sin patrón de pincel.
  • Qt.SolidPattern: Color uniforme.
  • Qt.Dense1Pattern: Patrón de pincel extremadamente denso.
  • Qt.HorPattern: Líneas horizontales.
  • Qt.VerPattern: Líneas verticales.
  • Qt.CrossPattern: Líneas horizontales y verticales cruzadas.
  • Qt.BDiagPattern: Líneas diagonales hacia atrás.
  • Qt.FDiagPattern: Líneas diagonales hacia adelante.
  • Qt.DiagCrossPattern: Líneas diagonales cruzadas.

Objetos QColor Predefinidos

  • Qt.white, Qt.black, Qt.red, Qt.darkRed, Qt.green, Qt.darkGreen, Qt.blue, Qt.cyan, Qt.magenta, Qt.yellow, Qt.darkYellow, Qt.gray.
import sys from PyQt5.QtCore import Qt, QPoint from PyQt5.QtGui import QPainter, QColor, QFont, QPixmap, QBrush from PyQt5.QtWidgets import QApplication, QWidget class Example(QWidget): def __init__(self): super(Example, self).__init__() self.initUI() def initUI(self): self.setGeometry(100,100, 400,300) self.setWindowTitle('Demo de Dibujo') self.show() def paintEvent(self, event): qp = QPainter() qp.begin(self) qp.setPen(QColor(Qt.red)) qp.setFont(QFont('Arial', 20)) qp.drawText(10,50, "Hola Python") qp.setPen(QColor(Qt.blue)) qp.drawLine(10,100,100,100) qp.drawRect(10,150,150,100) qp.setPen(QColor(Qt.yellow)) qp.drawEllipse(100,50,100,50) # qp.drawPixmap(220,10,QPixmap("pythonlogo.png")) # Asume que 'pythonlogo.png' existe en el mismo directorio qp.fillRect(20,175,130,70,QBrush(Qt.SolidPattern)) qp.end() def main(): app = QApplication(sys.argv) ex = Example() sys.exit(app.exec_()) if __name__ == '__main__': main()

Funcionalidad del Portapapeles con QClipboard

La clase QClipboard proporciona acceso al portapapeles de todo el sistema, lo que permite copiar y pegar datos entre diferentes aplicaciones. Su funcionamiento es similar a la clase QDrag, utilizando tipos de datos MIME.

No.Método de QClipboardDescripción
1clear()Borra el contenido del portapapeles.
2setImage()Copia un QImage al portapapeles.
3setMimeData()Establece datos MIME en el portapapeles.
4setPixmap()Copia un objeto QPixmap al portapapeles.
5setText()Copia una cadena de texto al portapapeles.
6text()Recupera texto del portapapeles.

La señal dataChanged() se emite cada vez que cambian los datos en el portapapeles.

import sys from PyQt5.QtWidgets import QApplication, QWidget, QTextEdit, QPushButton, QVBoxLayout, QMessageBox class Example(QWidget): def __init__(self): super(Example, self).__init__() self.initUI() def initUI(self): hbox = QVBoxLayout() self.edit1 = QTextEdit() hbox.addWidget(self.edit1) self.btn1 = QPushButton("Copiar") hbox.addWidget(self.btn1) self.edit2 = QTextEdit() self.btn2 = QPushButton("Pegar") hbox.addWidget(self.edit2) hbox.addWidget(self.btn2) self.btn1.clicked.connect(self.copytext) self.btn2.clicked.connect(self.pastetext) self.setLayout(hbox) self.setGeometry(300, 300, 300, 200) self.setWindowTitle('Portapapeles') self.show() def copytext(self): clipboard.setText(self.edit1.toPlainText()) msg = QMessageBox() msg.setText(clipboard.text() + " copiado al portapapeles") msg.exec_() def pastetext(self): self.edit2.setText(clipboard.text()) if __name__ == '__main__': app = QApplication(sys.argv) clipboard = app.clipboard() ex = Example() ex.setWindowTitle("Ejemplo de Portapapeles") sys.exit(app.exec_())

Manejo de Imágenes con QPixmap

La clase QPixmap proporciona una representación fuera de pantalla de una imagen, optimizada para mostrarse en la pantalla. Se puede utilizar como un dispositivo de pintura o cargarla en otros widgets como etiquetas (QLabel) o botones (QPushButton). PyQt también tiene la clase QImage, optimizada para E/S y manipulaciones de píxeles; ambos formatos son interconvertibles.

¿Cómo crear una aplicación GUI en PyQt?
Crear una aplicación GUI simple usando PyQt implica los siguientes pasos: Importe módulos QtCore, QtGui y QtWidgets desde el paquete PyQt5. Cree un objeto de aplicación de la clase QApplication. Un objeto QWidget crea una ventana de nivel superior. Agregue el objeto QLabel en él. Establezca el título de la etiqueta como "hola mundo".

Tipos de Archivos de Imagen Soportados

  • BMP (Mapa de bits de Windows)
  • GIF (Formato de Intercambio Gráfico)
  • JPG (Joint Photographic Experts Group)
  • PNG (Gráficos de Red Portátiles)
  • PBM (Mapa de bits portátil)
  • PGM (Mapa de grises portátil)
  • PPM (Pixmap portátil)
  • XBM (Mapa de bits X11)
  • XPM (Mapa de píxeles X11)
No.Método de QPixmapDescripción
1copy()Copia datos de mapas de píxeles de un objeto QRect.
2fromImage()Convierte un objeto QImage en QPixmap.
3grabWidget()Crea un mapa de píxeles a partir del widget dado.
4grabWindow()Crea un mapa de píxeles de datos en una ventana.
5load()Carga un archivo de imagen como mapa de píxeles.
6save()Guarda el objeto QPixmap como un archivo.
7toImage()Convierte un QPixmap en QImage.
import sys from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QVBoxLayout from PyQt5.QtGui import QPixmap def window(): app = QApplication(sys.argv) win = QWidget() l1 = QLabel() l1.setPixmap(QPixmap("python.png")) # Asegúrate de que 'python.png' exista en el mismo directorio vbox = QVBoxLayout() vbox.addWidget(l1) win.setLayout(vbox) win.setWindowTitle("Demo de QPixmap") win.show() sys.exit(app.exec_()) if __name__ == '__main__': window()

Personalizando la Apariencia: Cambiando el Color de la Ventana

Para cambiar el color de fondo de una ventana o cualquier otro widget en PyQt, puedes utilizar el método setStyleSheet(). Este método permite aplicar estilos CSS (Cascading Style Sheets) directamente a los widgets, ofreciendo una gran flexibilidad para personalizar la apariencia de tu aplicación. Toma una cadena de texto como argumento, donde defines las reglas de estilo.

import sys from PyQt5.QtWidgets import QApplication, QWidget def window(): app = QApplication(sys.argv) w = QWidget() # Cambia el color de fondo de la ventana a un azul claro w.setStyleSheet("background-color: lightblue;") w.setGeometry(100,100,300,200) w.setWindowTitle("Ventana con Color") w.show() sys.exit(app.exec_()) if __name__ == '__main__': window()

¿Cómo Combinar Funciones Relacionadas con Python y PyQt?

La verdadera potencia de PyQt reside en su capacidad para combinar las capacidades de la biblioteca Qt con la flexibilidad y simplicidad de Python. Esto se logra mediante la conexión de las señales emitidas por los widgets de PyQt a funciones o métodos Python personalizados (los slots). De esta manera, puedes escribir la lógica de tu aplicación en Python puro y hacer que interactúe directamente con la interfaz gráfica creada con PyQt. Por ejemplo, un clic en un botón (señal) puede disparar una función Python que realiza cálculos, accede a una base de datos o actualiza otro widget.

PyQt no es solo un envoltorio; es una integración profunda que permite a los desarrolladores de Python construir aplicaciones de escritorio complejas y de alto rendimiento que aprovechan al máximo el ecosistema de Qt. Al seguir un enfoque orientado a objetos, puedes encapsular la lógica de tu interfaz de usuario y la lógica de negocio de tu aplicación en clases separadas, lo que resulta en un código más organizado, mantenible y escalable.

Preguntas Frecuentes sobre PyQt

¿Qué es PyQt y para qué se usa?

PyQt es un conjunto de enlaces de Python para el framework de aplicaciones multiplataforma Qt. Se utiliza para crear interfaces gráficas de usuario (GUI) para aplicaciones de escritorio en sistemas operativos como Windows, Linux y macOS. Permite a los desarrolladores de Python construir aplicaciones visualmente ricas y funcionales.

¿Es PyQt gratuito?

PyQt tiene una licencia dual. Está disponible bajo la Licencia Pública General (GPL), lo que significa que es gratuito para proyectos de código abierto. Para proyectos comerciales o propietarios, se requiere una licencia comercial.

¿Cuál es la diferencia principal entre PyQt4 y PyQt5?

La diferencia más notable es la sintaxis de conexión de señales y slots (widget.signal.connect(slot_function) en PyQt5), la redistribución de clases entre módulos (por ejemplo, muchos widgets se movieron de QtGui a QtWidgets), y la eliminación del soporte para versiones muy antiguas de Python.

¿Necesito saber C++ para usar PyQt?

No, no necesitas saber C++ para usar PyQt. PyQt es una interfaz de Python para la biblioteca Qt, lo que significa que puedes usar todas las funcionalidades de Qt directamente desde Python. Sin embargo, tener una comprensión básica de los conceptos de Qt (como señales y slots) puede ser útil.

¿Puedo diseñar mi interfaz gráficamente sin escribir código?

Sí, puedes usar Qt Designer, una herramienta visual que viene con PyQt, para diseñar tu interfaz de usuario arrastrando y soltando widgets. Una vez que el diseño está completo, puedes guardar el archivo .ui y convertirlo a código Python usando la utilidad pyuic5.

¿Cómo manejo eventos de usuario como clics de botón?

En PyQt, los eventos se manejan utilizando el mecanismo de señales y slots. Los widgets emiten 'señales' cuando ocurre un evento (por ejemplo, un botón es clicado), y tú 'conectas' esas señales a funciones o métodos Python (los 'slots') que contienen la lógica que deseas ejecutar en respuesta al evento.

¿PyQt soporta bases de datos?

Sí, PyQt incluye el módulo QtSql, que proporciona clases para interactuar con diversas bases de datos SQL como SQLite, MySQL, PostgreSQL, y otras. Esto permite a tu aplicación PyQt almacenar y recuperar datos de manera eficiente.

Si quieres conocer otros artículos parecidos a PyQt: Creando Aplicaciones de Escritorio con Python puedes visitar la categoría Librerías.

Subir