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: