PyQt - Guía rápida

PyQt es un conjunto de herramientas de widgets GUI. Es una interfaz de Python paraQt, una de las bibliotecas GUI multiplataforma más poderosas y populares. PyQt fue desarrollado por RiverBank Computing Ltd. La última versión de PyQt se puede descargar desde su sitio web oficial: riverbankcomputing.com

La API de PyQt es un conjunto de módulos que contiene una gran cantidad de clases y funciones. MientrasQtCore El módulo contiene funcionalidad no GUI para trabajar con archivos y directorios, etc. QtGuiEl módulo contiene todos los controles gráficos. Además, existen módulos para trabajar con XML(QtXml), SVG (QtSvg)y SQL (QtSql)etc.

Entornos de apoyo

PyQt es compatible con todos los sistemas operativos populares, incluidos Windows, Linux y Mac OS. Tiene licencia doble, disponible bajo GPL y licencia comercial.

Ventanas

Puede descargar e instalar un instalador adecuado desde el enlace de descarga anterior correspondiente a la versión de Python (2.7 o 3.4) y la arquitectura de hardware (32 bits o 64 bits). Tenga en cuenta que hay dos versiones de PyQt disponibles, a saber,PyQt 4.8 y PyQt 5.5.

Si bien PyQt4 está disponible para Python 2 y Python 3, PyQt5 solo se puede usar junto con Python 3. *.

PyQt4 Windows Binaries

PyQt4-4.11.4-gpl-Py3.4-Qt4.8.7-x64.exe Instalador de Windows de 64 bits
PyQt4-4.11.4-gpl-Py3.4-Qt4.8.7-x32.exe Instalador de Windows de 32 bits
PyQt4-4.11.4-gpl-Py3.4-Qt5.5.0-x64.exe Instalador de Windows de 64 bits
PyQt4-4.11.4-gpl-Py3.4-Qt5.5.0-x32.exe Instalador de Windows de 32 bits
PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x64.exe Instalador de Windows de 64 bits
PyQt4-4.11.4-gpl-Py2.7-Qt4.8.7-x32.exe Instalador de Windows de 32 bits

PyQt5 Windows Binaries

PyQt5-5.5-gpl-Py3.4-Qt5.5.0-x64.exe Instalador de Windows de 64 bits
PyQt5-5.5-gpl-Py3.4-Qt5.5.0-x32.exe Instalador de Windows de 32 bits

Linux

Para Ubuntu o cualquier otra distribución de Debian Linux, use el siguiente comando para instalar PyQt:

sudo apt-get install python-qt4
or 
sudo apt-get install pyqt5-dev-tools

También puede compilar a partir del código fuente disponible en la página de "descarga".

PyQt-x11-gpl-4.11.4.tar.gz Linux, fuente UNIX para PyQt4
PyQt-gpl-5.5.tar.gz Fuente Linux, UNIX, MacOS / X para PyQt5

Mac OS

Proyecto PyQtX (http://sourceforge.net/projects/pyqtx/) aloja binarios de PyQt para Mac. Use el instalador Homebrew según el siguiente comando:

brew install pyqt

Crear una aplicación GUI simple usando PyQt implica los siguientes pasos:

  • Importar módulo QtGui.

  • Cree un objeto de aplicación.

  • 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".

  • Defina el tamaño y la posición de la ventana mediante el método setGeometry ().

  • Ingrese al bucle principal de la aplicación app.exec_() método.

import sys
from PyQt4 import QtGui

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

El código anterior produce la siguiente salida:

PyQt APIes una gran colección de clases y métodos. Estas clases están definidas en más de 20 módulos. A continuación se muestran algunos de los módulos de uso frecuente:

No Señor. Módulos y descripción
1

QtCore

Clases principales que no son GUI utilizadas por otros módulos

2

QtGui

Componentes de la interfaz gráfica de usuario

3

QtMultimedia

Clases de programación multimedia de bajo nivel

4

QtNetwork

Clases de programación de redes

5

QtOpenGL

Clases de soporte de OpenGL

6

QtScript

Clases para evaluar Qt Scripts

7

QtSql

Clases para la integración de bases de datos usando SQL

8

QtSvg

Clases para mostrar el contenido de archivos SVG

9

QtWebKit

Clases para renderizar y editar HTML

10

QtXml

Clases para manejar XML

11

QtAssistant

Soporte para ayuda en línea

12

QtDesigner

Clases para ampliar Qt Designer

La API de PyQt contiene más de 400 clases. losQObjectla clase está en la parte superior de la jerarquía de clases. Es la clase base de todos los objetos Qt. Adicionalmente,QPaintDevice class es la clase base para todos los objetos que se pueden pintar.

QApplicationclass administra la configuración principal y el flujo de control de una aplicación GUI. Contiene el bucle de eventos principal dentro del cual los eventos generados por los elementos de la ventana y otras fuentes se procesan y envían. También maneja configuraciones de todo el sistema y de toda la aplicación.

QWidget class, derivada de las clases QObject y QPaintDevice es la clase base para todos los objetos de la interfaz de usuario. QDialog y QFramelas clases también se derivan de la clase QWidget. Tienen su propio sistema de subclases.

Los siguientes diagramas representan algunas clases importantes en su jerarquía.

Aquí hay una lista selecta de widgets de uso frecuente:

A continuación se muestran los widgets más utilizados.

No Señor. Widgets y descripción
1

QLabel

Se usa para mostrar texto o imagen

2

QLineEdit

Permite al usuario ingresar una línea de texto

3

QTextEdit

Permite al usuario ingresar texto de varias líneas

4

QPushButton

Un botón de comando para invocar la acción

5

QRadioButton

Permite elegir una entre múltiples opciones.

6

QCheckBox

Permite elegir entre más de una opción

7

QSpinBox

Permite aumentar / disminuir un valor entero

8

QScrollBar

Permite acceder al contenido de un widget más allá de la apertura de la pantalla.

9

QSlider

Permite cambiar el valor límite linealmente.

10

QComboBox

Proporciona una lista desplegable de elementos para seleccionar

11

QMenuBar

Barra horizontal que contiene objetos QMenu

12

QStatusBar

Por lo general, en la parte inferior de QMainWindow, proporciona información de estado.

13

QToolBar

Por lo general, en la parte superior de QMainWindow o flotando. Contiene botones de acción

14

QListView

Proporciona una lista seleccionable de elementos en ListMode o IconMode

15

QPixmap

Representación de imágenes fuera de la pantalla para mostrarlas en objetos QLabel o QPushButton

dieciséis

QDialog

Ventana modal o no modal que puede devolver información a la ventana principal

La ventana de nivel superior de una aplicación basada en GUI típica es creada por QMainWindowobjeto widget. Algunos widgets como se enumeran anteriormente ocupan el lugar designado en esta ventana principal, mientras que otros se colocan en el área central de widgets utilizando varios administradores de diseño.

El siguiente diagrama muestra el marco QMainWindow:

El instalador de PyQt viene con una herramienta de creación de GUI llamada Qt Designer. Con su sencilla interfaz de arrastrar y soltar, se puede construir rápidamente una interfaz gráfica de usuario sin tener que escribir el código. Sin embargo, no es un IDE como Visual Studio. Por lo tanto, Qt Designer no tiene la capacidad de depurar y construir la aplicación.

La creación de una interfaz gráfica de usuario con Qt Designer comienza con la elección de una ventana de nivel superior para la aplicación.

A continuación, puede arrastrar y soltar los widgets necesarios desde el cuadro de widgets del panel izquierdo. También puede asignar valor a las propiedades del widget colocadas en el formulario.

El formulario diseñado se guarda como demo.ui. Este archivo de interfaz de usuario contiene una representación XML de los widgets y sus propiedades en el diseño. Este diseño se traduce al equivalente de Python utilizando la utilidad de línea de comandos pyuic4. Esta utilidad es un contenedor para el módulo uic. El uso de pyuic4 es el siguiente:

pyuic4 –x demo.ui –o demo.py

En el comando anterior, el modificador -x agrega una pequeña cantidad de código adicional al XML generado para que se convierta en una aplicación independiente autoejecutable.

if __name__ == "__main__":
   import sys
   app = QtGui.QApplication(sys.argv)
   Dialog = QtGui.QDialog()
   ui = Ui_Dialog()
   ui.setupUi(Dialog)
   Dialog.show()
   sys.exit(app.exec_())

La secuencia de comandos de Python resultante se ejecuta para mostrar el siguiente cuadro de diálogo:

El usuario puede ingresar datos en los campos de entrada pero hacer clic en el botón Agregar no generará ninguna acción ya que no está asociado con ninguna función. Reaccionar a la respuesta generada por el usuario se llama comoevent handling.

A diferencia de una aplicación en modo de consola, que se ejecuta de manera secuencial, una aplicación basada en GUI está impulsada por eventos. Las funciones o métodos se ejecutan en respuesta a las acciones del usuario, como hacer clic en un botón, seleccionar un elemento de una colección o un clic del mouse, etc., llamadoevents.

Los widgets que se utilizan para construir la interfaz GUI actúan como fuente de tales eventos. Cada widget de PyQt, que se deriva de la clase QObject, está diseñado para emitir 'signal'en respuesta a uno o más eventos. La señal por sí sola no realiza ninguna acción. En cambio, está 'conectado' a un 'slot'. La ranura puede ser cualquieracallable Python function.

En PyQt, la conexión entre una señal y una ranura se puede lograr de diferentes maneras. A continuación se muestran las técnicas más utilizadas:

QtCore.QObject.connect(widget, QtCore.SIGNAL(‘signalname’), slot_function)

Una forma más conveniente de llamar a slot_function, cuando un widget emite una señal, es la siguiente:

widget.signal.connect(slot_function)

Supongamos que se va a llamar a una función cuando se hace clic en un botón. Aquí, la señal pulsada se conectará a una función invocable. Se puede lograr en cualquiera de las siguientes dos técnicas:

QtCore.QObject.connect(button, QtCore.SIGNAL(“clicked()”), slot_function)

o

button.clicked.connect(slot_function)

Ejemplo

En el siguiente ejemplo, se agregan dos objetos QPushButton (b1 y b2) en la ventana QDialog. Queremos llamar a las funciones b1_clicked () y b2_clicked () al hacer clic en b1 y b2 respectivamente.

Cuando se hace clic en b1, la señal de clic () se conecta a la función b1_clicked ()

b1.clicked.connect(b1_clicked())

Cuando se hace clic en b2, la señal de clic () se conecta a la función b2_clicked ()

QObject.connect(b2, SIGNAL("clicked()"), b2_clicked)

Ejemplo

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

def window():
   app = QApplication(sys.argv)
   win = QDialog()
   b1 = QPushButton(win)
   b1.setText("Button1")
   b1.move(50,20)
   b1.clicked.connect(b1_clicked)

   b2 = QPushButton(win)
   b2.setText("Button2")
   b2.move(50,50)
   QObject.connect(b2,SIGNAL("clicked()"),b2_clicked)

   win.setGeometry(100,100,200,100)
   win.setWindowTitle("PyQt")
   win.show()
   sys.exit(app.exec_())

def b1_clicked():
   print "Button 1 clicked"

def b2_clicked():
   print "Button 2 clicked"

if __name__ == '__main__':
   window()

El código anterior produce la siguiente salida:

Salida

Button 1 clicked
Button 2 clicked

Un widget GUI se puede colocar dentro de la ventana del contenedor especificando sus coordenadas absolutas medidas en píxeles. Las coordenadas son relativas a las dimensiones de la ventana definidas por el método setGeometry ().

sintaxis de setGeometry ()

QWidget.setGeometry(xpos, ypos, width, height)

En el siguiente fragmento de código, la ventana de nivel superior con dimensiones de 300 por 200 píxeles se muestra en la posición (10, 10) del monitor.

import sys
from PyQt4 import QtGui

def window():
   app = QtGui.QApplication(sys.argv)
   w = QtGui.QWidget()
	
   b = QtGui.QPushButton(w)
   b.setText("Hello World!")
   b.move(50,20)
	
   w.setGeometry(10,10,300,200)
   w.setWindowTitle(“PyQt”)
   w.show()
   sys.exit(app.exec_())
	
if __name__ == '__main__':
   window()

UN PushButton El widget se agrega en la ventana y se coloca en una posición 50 píxeles hacia la derecha y 20 píxeles debajo de la posición superior izquierda de la ventana.

Esta Absolute Positioning, sin embargo, no es adecuado debido a las siguientes razones:

  • La posición del widget no cambia incluso si se cambia el tamaño de la ventana.

  • Es posible que la apariencia no sea uniforme en diferentes dispositivos de visualización con diferentes resoluciones.

  • La modificación en el diseño es difícil ya que puede necesitar rediseñar todo el formulario.

La API de PyQt proporciona clases de diseño para una gestión más elegante del posicionamiento de los widgets dentro del contenedor. Las ventajas de los administradores de diseño sobre el posicionamiento absoluto son:

  • Los widgets dentro de la ventana cambian de tamaño automáticamente.

  • Garantiza una apariencia uniforme en dispositivos de visualización con diferentes resoluciones.

  • Es posible agregar o eliminar widgets dinámicamente sin tener que rediseñar.

Aquí está la lista de clases que discutiremos una por una en este capítulo.

No Señor. Clases y descripción
1 QBoxLayout

La clase QBoxLayout alinea los widgets vertical u horizontalmente. Sus clases derivadas son QVBoxLayout (para organizar widgets verticalmente) y QHBoxLayout (para organizar widgets horizontalmente).

2 QGridLayout

Un objeto de clase GridLayout se presenta con una cuadrícula de celdas dispuestas en filas y columnas. La clase contiene el método addWidget (). Se puede agregar cualquier widget especificando el número de filas y columnas de la celda.

3 QFormLayout

QFormLayout es una forma conveniente de crear un formulario de dos columnas, donde cada fila consta de un campo de entrada asociado con una etiqueta. Como convención, la columna de la izquierda contiene la etiqueta y la columna de la derecha contiene un campo de entrada.

Aquí está la lista de widgets que discutiremos uno por uno en este capítulo.

No Señor Widgets y descripción
1 QLabel

Un objeto QLabel actúa como un marcador de posición para mostrar texto o imagen no editable, o una película de GIF animado. También se puede utilizar como clave mnemotécnica para otros widgets.

2 QLineEdit

El objeto QLineEdit es el campo de entrada más utilizado. Proporciona un cuadro en el que se puede ingresar una línea de texto. Para ingresar texto de varias líneas, se requiere el objeto QTextEdit.

3 QPushButton

En la API de PyQt, el objeto de la clase QPushButton presenta un botón que, cuando se hace clic, se puede programar para invocar una determinada función.

4 QRadioButton

Un objeto de clase QRadioButton presenta un botón seleccionable con una etiqueta de texto. El usuario puede seleccionar una de las muchas opciones presentadas en el formulario. Esta clase se deriva de la clase QAbstractButton.

5 QCheckBox

Aparece un cuadro rectangular antes de la etiqueta de texto cuando se agrega un objeto QCheckBox a la ventana principal. Al igual que QRadioButton, también es un botón seleccionable.

6 QComboBox

Un objeto QComboBox presenta una lista desplegable de elementos para seleccionar. Se necesita un espacio de pantalla mínimo en el formulario requerido para mostrar solo el elemento seleccionado actualmente.

7 QSpinBox

Un objeto QSpinBox presenta al usuario un cuadro de texto que muestra un número entero con el botón arriba / abajo a su derecha.

8 Widget y señal QSlider

El objeto de clase QSlider presenta al usuario una ranura sobre la que se puede mover un asa. Es un widget clásico para controlar un valor acotado.

9 QMenuBar, QMenu y QAction

Una QMenuBar horizontal justo debajo de la barra de título de un objeto QMainWindow está reservada para mostrar objetos QMenu.

10 QToolBar

Un widget QToolBar es un panel móvil que consta de botones de texto, botones con iconos u otros widgets.

11 QInputDialog

Este es un diálogo preconfigurado con un campo de texto y dos botones, Aceptar y Cancelar. La ventana principal recopila la entrada en el cuadro de texto después de que el usuario hace clic en el botón Aceptar o presiona Entrar.

12 QFontDialog

Otro cuadro de diálogo de uso común, un widget selector de fuentes, es la apariencia visual de la clase QDialog. El resultado de este diálogo es un objeto Qfont, que puede ser consumido por la ventana principal.

13 QFileDialog

Este widget es un cuadro de diálogo de selección de archivos. Permite al usuario navegar por el sistema de archivos y seleccionar un archivo para abrir o guardar. El diálogo se invoca a través de funciones estáticas o llamando a la función exec_ () en el objeto de diálogo.

14 QTab

Si un formulario tiene demasiados campos para mostrarse simultáneamente, se pueden organizar en diferentes páginas ubicadas debajo de cada pestaña de un widget con pestañas. El QTabWidget proporciona una barra de pestañas y un área de página.

15 QStacked

El funcionamiento de QStackedWidget es similar al de QTabWidget. También ayuda en el uso eficiente del área de clientes de Windows.

dieciséis QSplitter

Si un formulario tiene demasiados campos para mostrarse simultáneamente, se pueden organizar en diferentes páginas ubicadas debajo de cada pestaña de un widget con pestañas. El QTabWidget proporciona una barra de pestañas y un área de página.

17 QDock

Una ventana acoplable es una subventana que puede permanecer en estado flotante o puede adjuntarse a la ventana principal en una posición específica. El objeto de ventana principal de la clase QMainWindow tiene un área reservada para ventanas acoplables.

18 QStatusBar

El objeto QMainWindow reserva una barra horizontal en la parte inferior como barra de estado. Se utiliza para mostrar información de estado permanente o contextual.

19 QList

La clase QListWidget es una interfaz basada en elementos para agregar o eliminar elementos de una lista. Cada elemento de la lista es un objeto QListWidgetItem. ListWidget se puede configurar para que sea multiseleccionable.

20 QScrollBar

Un control de barra de desplazamiento permite al usuario acceder a partes del documento que están fuera del área visible. Proporciona un indicador visual de la posición actual.

21 QCalendar

El widget QCalendar es un útil control de selección de fechas. Proporciona una vista mensual. El usuario puede seleccionar la fecha mediante el uso del mouse o el teclado, siendo la fecha de hoy la predeterminada.

UN QDialogEl widget presenta una ventana de nivel superior que se utiliza principalmente para recopilar la respuesta del usuario. Puede configurarse para serModal (donde bloquea su ventana principal) o Modeless (la ventana de diálogo se puede omitir).

La API de PyQt tiene varios widgets de diálogo preconfigurados, como InputDialog, FileDialog, FontDialog, etc.

Ejemplo

En el siguiente ejemplo, el atributo WindowModality de la ventana Dialog decide si es modal o no modal. Cualquier botón del cuadro de diálogo se puede configurar como predeterminado. El método QDialog.reject () descarta el diálogo cuando el usuario presiona la tecla Escape.

Un PushButton en una ventana de QWidget de nivel superior, cuando se hace clic, produce una ventana de diálogo. Un cuadro de diálogo no tiene controles para minimizar y maximizar en su barra de título.

El usuario no puede relegar este cuadro de diálogo en segundo plano porque su WindowModality está establecido en ApplicationModal.

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

def window():
   app = QApplication(sys.argv)
   w = QWidget()
   b = QPushButton(w)
   b.setText("Hello World!")
   b.move(50,50)
   b.clicked.connect(showdialog)
   w.setWindowTitle("PyQt Dialog demo")
   w.show()
   sys.exit(app.exec_())
	
def showdialog():
   d = QDialog()
   b1 = QPushButton("ok",d)
   b1.move(50,50)
   d.setWindowTitle("Dialog")
   d.setWindowModality(Qt.ApplicationModal)
   d.exec_()
	
if __name__ == '__main__':
   window()

El código anterior produce la siguiente salida:

QMessageBoxes un cuadro de diálogo modal de uso común para mostrar algún mensaje informativo y, opcionalmente, pedirle 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.

Los métodos y enumeraciones importantes asociados con la clase QMessageBox se proporcionan en la siguiente tabla:

No Señor. Métodos y descripción
1

setIcon()

Muestra el icono predefinido correspondiente a la gravedad del mensaje

Pregunta

Información

Advertencia

Crítico

2

setText()

Establece el texto del mensaje principal que se mostrará

3

setInformativeText()

Muestra información adicional

4

setDetailText()

El cuadro de diálogo muestra un botón Detalles. Este texto aparece al hacer clic en él.

5

setTitle()

Muestra el título personalizado del diálogo

6

setStandardButtons()

Lista de botones estándar que se mostrarán. Cada botón está asociado con

QMessageBox.Ok 0x00000400

QMessageBox.Open 0x00002000

QMessageBox.Save 0x00000800

QMessageBox.Cancel 0x00400000

QMessageBox.Close 0x00200000

QMessageBox.Yes 0x00004000

QMessageBox.No 0x00010000

QMessageBox.Abort 0x00040000

QMessageBox.Reintentar 0x00080000

QMessageBox.Ignore 0x00100000

7

setDefaultButton()

Establece el botón como predeterminado. Emite la señal de clic si se presiona Enter

8

setEscapeButton()

Configura el botón para que se trate como si se hiciera clic si se presiona la tecla Escape

Ejemplo

En el siguiente ejemplo, haga clic en la señal del botón en la ventana de nivel superior, la función conectada muestra el cuadro de diálogo del cuadro de mensaje.

msg = QMessageBox()
msg.setIcon(QMessageBox.Information)
msg.setText("This is a message box")
msg.setInformativeText("This is additional information")
msg.setWindowTitle("MessageBox demo")
msg.setDetailedText("The details are as follows:")

La función setStandardButton () muestra los botones deseados.

msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)

La señal buttonClicked () está conectada a una función de ranura, que identifica el título de la fuente de la señal.

msg.buttonClicked.connect(msgbtn)

El código completo para el ejemplo es el siguiente:

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

def window():
   app = QApplication(sys.argv)
   w = QWidget()
   b = QPushButton(w)
   b.setText("Show message!")

   b.move(50,50)
   b.clicked.connect(showdialog)
   w.setWindowTitle("PyQt Dialog demo")
   w.show()
   sys.exit(app.exec_())
	
def showdialog():
   msg = QMessageBox()
   msg.setIcon(QMessageBox.Information)

   msg.setText("This is a message box")
   msg.setInformativeText("This is additional information")
   msg.setWindowTitle("MessageBox demo")
   msg.setDetailedText("The details are as follows:")
   msg.setStandardButtons(QMessageBox.Ok | QMessageBox.Cancel)
   msg.buttonClicked.connect(msgbtn)
	
   retval = msg.exec_()
   print "value of pressed message box button:", retval
	
def msgbtn(i):
   print "Button pressed is:",i.text()
	
if __name__ == '__main__': 
   window()

El código anterior produce la siguiente salida:

Una aplicación de GUI típica puede tener varias ventanas. Los widgets con pestañas y apilados permiten activar una de esas ventanas a la vez. Sin embargo, muchas veces este enfoque puede no ser útil ya que la vista de otras ventanas está oculta.

Una forma de mostrar varias ventanas simultáneamente es crearlas como ventanas independientes. Esto se denomina SDI (interfaz de documento único). Esto requiere más recursos de memoria ya que cada ventana puede tener su propio sistema de menú, barra de herramientas, etc.

Las aplicaciones MDI (Multiple Document Interface) consumen menos recursos de memoria. Las subventanas se colocan dentro del contenedor principal en relación entre sí. El widget contenedor se llamaQMdiArea.

El widget QMdiArea generalmente ocupa el widget central del objeto QMainWondow. Las ventanas secundarias de esta área son instancias de la clase QMdiSubWindow. Es posible configurar cualquier QWidget como el widget interno del objeto subWindow. Las subventanas en el área de MDI pueden disponerse en cascada o en mosaico.

La siguiente tabla enumera métodos importantes de la clase QMdiArea y la clase QMdiSubWindow:

No Señor. Métodos y descripción
1

addSubWindow()

Agrega un widget como una nueva subventana en el área MDI

2

removeSubWindow()

Elimina un widget que es un widget interno de una subventana

3

setActiveSubWindow()

Activa una subventana

4

cascadeSubWindows()

Organiza subventanas en MDiArea en cascada

5

tileSubWindows()

Organiza subventanas en MDiArea en forma de mosaico

6

closeActiveSubWindow()

Cierra la subventana activa

7

subWindowList()

Devuelve la lista de subventanas en el área MDI

8

setWidget()

Establece un QWidget como un widget interno de una instancia de QMdiSubwindow

El objeto QMdiArea emite la señal subWindowActivated () mientras que el objeto QMdisubWindow emite la señal windowStateChanged ().

Ejemplo

En el siguiente ejemplo, la ventana de nivel superior que comprende QMainWindow tiene un menú y MdiArea.

self.mdi = QMdiArea()
self.setCentralWidget(self.mdi)
bar = self.menuBar()
file = bar.addMenu("File")

file.addAction("New")
file.addAction("cascade")
file.addAction("Tiled")

La señal activada () del menú está conectada a la función de acción de ventana ().

file.triggered[QAction].connect(self.windowaction)

La nueva acción de menú agrega una subventana en el área de MDI con un título que tiene un número incremental.

MainWindow.count = MainWindow.count+1
sub = QMdiSubWindow()
sub.setWidget(QTextEdit())
sub.setWindowTitle("subwindow"+str(MainWindow.count))
self.mdi.addSubWindow(sub)
sub.show()

Los botones en cascada y en mosaico del menú organizan las subventanas que se muestran actualmente en cascada y en mosaico, respectivamente.

El código completo es el siguiente:

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

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("File")
      file.addAction("New")
      file.addAction("cascade")
      file.addAction("Tiled")
      file.triggered[QAction].connect(self.windowaction)
      self.setWindowTitle("MDI demo")
		
   def windowaction(self, q):
      print "triggered"
		
   if q.text() == "New":
      MainWindow.count = MainWindow.count+1
      sub = QMdiSubWindow()
      sub.setWidget(QTextEdit())
      sub.setWindowTitle("subwindow"+str(MainWindow.count))
      self.mdi.addSubWindow(sub)
      sub.show()
		
   if q.text() == "cascade":
      self.mdi.cascadeSubWindows()
		
   if q.text() == "Tiled":
      self.mdi.tileSubWindows()
		
   def main():
      app = QApplication(sys.argv)
      ex = MainWindow()
      ex.show()
      sys.exit(app.exec_())
	
   if __name__ == '__main__':
      main()

El código anterior produce la siguiente salida:

La provisión de drag and dropes muy intuitivo para el usuario. Se encuentra en muchas aplicaciones de escritorio donde el usuario puede copiar o mover objetos de una ventana a otra.

La transferencia de datos de arrastrar y soltar basada en MIME se basa en la clase QDrag. QMimeDatalos objetos asocian los datos con su tipo MIME correspondiente. Se almacena en el portapapeles y luego se usa en el proceso de arrastrar y soltar.

Las siguientes funciones de la clase QMimeData permiten que el tipo MIME sea detectado y utilizado convenientemente.

Ensayador Adquiridor Setter Tipos MIME
hasText () texto() setText () Texto sin formato
hasHtml () html () setHtml () texto / html
hasUrls () urls () setUrls () texto / uri-list
hasImage () datos de imagen() setImageData () imagen / *
hasColor () colorData () setColorData () aplicación / x-color

Muchos objetos QWidget admiten la actividad de arrastrar y soltar. Aquellos que permiten que sus datos sean arrastrados tienen setDragEnabled () que debe establecerse en true. Por otro lado, los widgets deben responder a los eventos de arrastrar y soltar para almacenar los datos arrastrados a ellos.

  • DragEnterEvent proporciona un evento que se envía al widget de destino cuando la acción de arrastre lo ingresa.

  • DragMoveEvent se utiliza cuando la acción de arrastrar y soltar está en curso.

  • DragLeaveEvent se genera cuando la acción de arrastrar y soltar sale del widget.

  • DropEvent, por otro lado, ocurre cuando se completa la caída. La acción propuesta por el evento puede aceptarse o rechazarse condicionalmente.

Ejemplo

En el siguiente código, DragEnterEvent verifica si los datos MIME del evento contienen texto. En caso afirmativo, se acepta la acción propuesta del evento y el texto se agrega como un nuevo elemento en el ComboBox.

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class combo(QComboBox):

   def __init__(self, title, parent):
      super(combo, self).__init__( parent)
	
      self.setAcceptDrops(True)
		
   def dragEnterEvent(self, e):
      print 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("Type some text in textbox and drag it into combo box"))
		
      edit = QLineEdit()
      edit.setDragEnabled(True)
      com = combo("Button", self)
      lo.addRow(edit,com)
      self.setLayout(lo)
      self.setWindowTitle('Simple drag & drop')
		
def main():
   app = QApplication(sys.argv)
   ex = Example()
   ex.show()
   app.exec_()
	
if __name__ == '__main__':
   main()

El código anterior produce la siguiente salida:

La API de PyQt contiene un elaborado sistema de clases para comunicarse con muchas bases de datos basadas en SQL. Su QSqlDatabase proporciona acceso a través de un objeto Connection. A continuación se muestra la lista de controladores SQL disponibles actualmente:

No Señor. Tipo de controlador y descripción
1

QDB2

IBM DB2

2

QIBASE

Controlador Borland InterBase

3

QMYSQL

Controlador MySQL

4

QOCI

Controlador de interfaz de llamada de Oracle

5

QODBC

Controlador ODBC (incluye Microsoft SQL Server)

6

QPSQL

Controlador PostgreSQL

7

QSQLITE

SQLite versión 3 o superior

8

QSQLITE2

SQLite versión 2

Ejemplo

Se establece una conexión con una base de datos SQLite mediante el método estático:

db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('sports.db')

Otros métodos de la clase QSqlDatabase son los siguientes:

No Señor. Métodos y descripción
1

setDatabaseName()

Establece el nombre de la base de datos con la que se busca la conexión.

2

setHostName()

Establece el nombre del host en el que está instalada la base de datos.

3

setUserName()

Especifica el nombre de usuario para la conexión.

4

setPassword()

Establece la contraseña del objeto de conexión, si la hubiera

5

commit()

Confirma las transacciones y devuelve verdadero si tiene éxito

6

rollback()

Revierte la transacción de la base de datos

7

close()

Cierra la conexión

La clase QSqlQuery tiene la funcionalidad para ejecutar y manipular comandos SQL. Se pueden ejecutar consultas SQL de tipo DDL y DML. El método más importante de la clase es exec_ (), que toma como argumento una cadena que contiene una declaración SQL para ser ejecutada.

query = QtSql.QSqlQuery()
query.exec_("create table sportsmen(id int primary key, 
   " "firstname varchar(20), lastname varchar(20))")

El siguiente script crea una base de datos de SQLite sports.db con una tabla de deportista poblada con cinco registros.

from PyQt4 import QtSql, QtGui

def createDB():
   db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
   db.setDatabaseName('sports.db')
	
   if not db.open():
      QtGui.QMessageBox.critical(None, QtGui.qApp.tr("Cannot open database"),
         QtGui.qApp.tr("Unable to establish a database connection.\n"
            "This example needs SQLite support. Please read "
            "the Qt SQL driver documentation for information "
            "how to build it.\n\n" "Click Cancel to exit."),
         QtGui.QMessageBox.Cancel)
			
      return False
		
   query = QtSql.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__':
   import sys
	
   app = QtGui.QApplication(sys.argv)
   createDB()

La clase QSqlTableModel en PyQt es una interfaz de alto nivel que proporciona un modelo de datos editable para leer y escribir registros en una sola tabla. Este modelo se utiliza para poblar un objeto QTableView. Presenta al usuario una vista desplazable y editable que se puede colocar en cualquier ventana de nivel superior.

Un objeto QTableModel se declara de la siguiente manera:

model = QtSql.QSqlTableModel()

Su estrategia de edición se puede establecer en cualquiera de los siguientes:

QSqlTableModel.OnFieldChange Todos los cambios se aplicarán inmediatamente.
QSqlTableModel.OnRowChange Los cambios se aplicarán cuando el usuario seleccione una fila diferente
QSqlTableModel.OnManualSubmit Todos los cambios se almacenarán en caché hasta que se llame a submitAll () o revertAll ()

Ejemplo

En el siguiente ejemplo, la tabla de deportistas se usa como modelo y la estrategia se establece como:

model.setTable('sportsmen') 
model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)

   model.select()

La clase QTableView es parte del marco Model / View en PyQt. El objeto QTableView se crea de la siguiente manera:

view = QtGui.QTableView()
view.setModel(model)
view.setWindowTitle(title)
return view

Este objeto QTableView y dos widgets QPushButton se agregan a la ventana QDialog de nivel superior. La señal pulsada () del botón añadir está conectada a addrow () que realiza insertRow () en la tabla del modelo.

button.clicked.connect(addrow)
def addrow():
   print model.rowCount()
   ret = model.insertRows(model.rowCount(), 1)
   print ret

La ranura asociada con el botón de eliminar ejecuta una función lambda que elimina una fila, que es seleccionada por el usuario.

btn1.clicked.connect(lambda: model.removeRow(view1.currentIndex().row()))

El código completo es el siguiente:

import sys
from PyQt4 import QtCore, QtGui, QtSql
import sportsconnection

def initializeModel(model):
   model.setTable('sportsmen')
   model.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
   model.select()
   model.setHeaderData(0, QtCore.Qt.Horizontal, "ID")
   model.setHeaderData(1, QtCore.Qt.Horizontal, "First name")
   model.setHeaderData(2, QtCore.Qt.Horizontal, "Last name")
	
def createView(title, model):
   view = QtGui.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):
   delrow = i.row()
	
if __name__ == '__main__':

   app = QtGui.QApplication(sys.argv)
   db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
   db.setDatabaseName('sports.db')
   model = QtSql.QSqlTableModel()
   delrow = -1
   initializeModel(model)
	
   view1 = createView("Table Model (View 1)", model)
   view1.clicked.connect(findrow)
	
   dlg = QtGui.QDialog()
   layout = QtGui.QVBoxLayout()
   layout.addWidget(view1)
	
   button = QtGui.QPushButton("Add a row")
   button.clicked.connect(addrow)
   layout.addWidget(button)
	
   btn1 = QtGui.QPushButton("del a row")
   btn1.clicked.connect(lambda: model.removeRow(view1.currentIndex().row()))
   layout.addWidget(btn1)
	
   dlg.setLayout(layout)
   dlg.setWindowTitle("Database Demo")
   dlg.show()
   sys.exit(app.exec_())

El código anterior produce la siguiente salida:

Todos QWidgetlas clases en PyQt están subclasificadas de la clase QPaintDevice. UNQPaintDevicees una abstracción de un espacio bidimensional que se puede dibujar con un QPainter. Las dimensiones del dispositivo de pintura se miden en píxeles comenzando desde la esquina superior izquierda.

La clase QPainter realiza pintura de bajo nivel en widgets y otros dispositivos que se pueden pintar, como una impresora. Normalmente, se usa en el evento de pintura del widget. losQPaintEvent ocurre siempre que se actualiza la apariencia del widget.

El pintor se activa llamando al método begin (), mientras que el método end () lo desactiva. En el medio, el patrón deseado se pinta con los métodos adecuados que se enumeran en la siguiente tabla.

No Señor. Métodos y descripción
1

begin()

Empieza a pintar en el dispositivo de destino

2

drawArc()

Dibuja un arco entre el ángulo inicial y final

3

drawEllipse()

Dibuja una elipse dentro de un rectángulo

4

drawLine()

Dibuja una línea con coordenadas de punto final especificadas

5

drawPixmap()

Extrae el mapa de píxeles del archivo de imagen y lo muestra en la posición especificada

6

drwaPolygon()

Dibuja un polígono usando una matriz de coordenadas

7

drawRect()

Dibuja un rectángulo comenzando en la coordenada superior izquierda con el ancho y alto dados

8

drawText()

Muestra el texto en las coordenadas dadas.

9

fillRect()

Rellena el rectángulo con el parámetro QColor

10

setBrush()

Establece un estilo de pincel para pintar

11

setPen()

Establece el color, el tamaño y el estilo del lápiz que se utilizará para dibujar.

Estilos QColor predefinidos

Qt.NoBrush Sin patrón de pincel
Qt. De patrón sólido Color uniforme
Qt. Denso1Patrón Patrón de pincel extremadamente denso
Qt.HorPattern Lineas horizontales
Qt.VerPattern Líneas verticales
Qt. De patrón Cruzando líneas horizontales y verticales
Qt.BDiagPattern Líneas diagonales hacia atrás
Qt.FDiagPattern Adelante líneas diagonales
Qt.DiagCrossPattern Cruzando líneas diagonales

Objetos QColor predefinidos

Qt. De blanco
Qt. Negro
Rojo cuarto
Qt.rojo oscuro
Qt. Verde
Qt.darkGreen
Qt. Azul
Cian
Qt. De magenta
Qt. De amarillo
Qt.darkYellow
Qt. De gris

El color personalizado se puede elegir especificando valores RGB, CMYK o HSV.

Ejemplo

El siguiente ejemplo implementa algunos de estos métodos.

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class Example(QWidget):

   def __init__(self):
      super(Example, self).__init__()
      self.initUI()
		
   def initUI(self):
      self.text = "hello world"
      self.setGeometry(100,100, 400,300)
      self.setWindowTitle('Draw Demo')
      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, "hello Pyth
		on")
      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("python.jpg"))
      qp.fillRect(200,175,150,100,QBrush(Qt.SolidPattern))
      qp.end()
		
def main():
   app = QApplication(sys.argv)
   ex = Example()
   sys.exit(app.exec_())
	
if __name__ == '__main__':
   main()

El código anterior produce la siguiente salida:

los QClipboardLa clase proporciona acceso al portapapeles de todo el sistema que ofrece un mecanismo simple para copiar y pegar datos entre aplicaciones. Su acción es similar a la de la clase QDrag y utiliza tipos de datos similares.

La clase QApplication tiene un método estático clipboard () que devuelve una referencia al objeto del portapapeles. Cualquier tipo de MimeData se puede copiar o pegar desde el portapapeles.

A continuación se muestran los métodos de clase del portapapeles que se utilizan comúnmente:

No Señor. Métodos y descripción
1

clear()

Borra el contenido del portapapeles

2

setImage()

Copia QImage en el portapapeles

3

setMimeData()

Establece datos MIME en el portapapeles

4

setPixmap()

Copia el objeto Pixmap en el portapapeles

5

setText()

Copia QString en el portapapeles

6

text()

Recupera texto del portapapeles

La señal asociada con el objeto del portapapeles es:

No Señor. Método y descripción
1

dataChanged()

Siempre que cambien los datos del portapapeles

Ejemplo

En el siguiente ejemplo, se agregan dos objetos TextEdit y dos Pushbuttons a una ventana de nivel superior.

Para empezar, se crea una instancia del objeto del portapapeles. El método Copy () del objeto textedit copia los datos en el portapapeles del sistema. Cuando se hace clic en el botón Pegar, recupera los datos del portapapeles y los pega en otro objeto de texto.

QPixmapLa clase proporciona una representación fuera de la pantalla de una imagen. Se puede utilizar como un objeto QPaintDevice o se puede cargar en otro widget, normalmente una etiqueta o un botón.

Qt API tiene otra clase QImage similar, que está optimizada para E / S y otras manipulaciones de píxeles. Pixmap, por otro lado, está optimizado para mostrarlo en la pantalla. Ambos formatos son interconvertibles.

Los tipos de archivos de imagen que se pueden leer en un objeto QPixmap son los siguientes:

BMP Mapa de bits de Windows
GIF Formato de intercambio gráfico (opcional)
JPG Joint Photographic Experts Group
JPEG 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

Los siguientes métodos son útiles para manejar el objeto QPixmap:

No Señor. Métodos y descripción
1

copy()

Copia datos de mapas de píxeles de un objeto QRect

2

fromImage()

Convierte el objeto QImage en QPixmap

3

grabWidget()

Crea un mapa de píxeles a partir del widget dado

4

grabWindow()

Crear mapa de píxeles de datos en una ventana

5

Load()

Carga un archivo de imagen como mapa de píxeles

6

save()

Guarda el objeto QPixmap como un archivo

7

toImage

Convierte un QPixmap en QImage

El uso más común de QPixmap es mostrar la imagen en una etiqueta / botón.

Ejemplo

El siguiente ejemplo muestra una imagen mostrada en un QLabel mediante el método setPixmap (). El código completo es el siguiente:

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

def window():
   app = QApplication(sys.argv)
   win = QWidget()
   l1 = QLabel()
   l1.setPixmap(QPixmap("python.jpg"))
	
   vbox = QVBoxLayout()
   vbox.addWidget(l1)
   win.setLayout(vbox)
   win.setWindowTitle("QPixmap Demo")
   win.show()
   sys.exit(app.exec_())
	
if __name__ == '__main__':
   window()

El código anterior produce la siguiente salida: