PyQt - Guia rápido

PyQt é um kit de ferramentas de widgets de GUI. É uma interface Python paraQt, uma das mais poderosas e populares bibliotecas de GUI de plataforma cruzada. O PyQt foi desenvolvido pela RiverBank Computing Ltd. A versão mais recente do PyQt pode ser baixada de seu site oficial - riverbankcomputing.com

PyQt API é um conjunto de módulos contendo um grande número de classes e funções. EnquantoQtCore módulo contém funcionalidade não-GUI para trabalhar com arquivo e diretório, etc., QtGuimódulo contém todos os controles gráficos. Além disso, existem módulos para trabalhar com XML(QtXml), SVG (QtSvg)e SQL (QtSql)etc.

Ambientes de Apoio

PyQt é compatível com todos os sistemas operacionais populares, incluindo Windows, Linux e Mac OS. É uma licença dupla, disponível sob GPL e também sob licença comercial.

janelas

Você pode baixar e instalar um instalador apropriado no link de download acima correspondente à versão do Python (2.7 ou 3.4) e arquitetura de hardware (32 ou 64 bits). Observe que existem duas versões do PyQt disponíveis, a saber,PyQt 4.8 e PyQt 5.5.

Enquanto PyQt4 está disponível para Python 2, bem como Python 3, PyQt5 pode ser usado junto com Python 3. * apenas.

PyQt4 Windows Binaries

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

PyQt5 Windows Binaries

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

Linux

Para Ubuntu ou qualquer outra distribuição debian Linux, use o seguinte comando para instalar o PyQt -

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

Você também pode construir a partir do código-fonte disponível na página de 'download'.

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

Mac OS

Projeto PyQtX (http://sourceforge.net/projects/pyqtx/) hospeda binários do PyQt para Mac. Use o instalador Homebrew de acordo com o seguinte comando -

brew install pyqt

A criação de um aplicativo GUI simples usando PyQt envolve as seguintes etapas -

  • Importar módulo QtGui.

  • Crie um objeto de aplicativo.

  • Um objeto QWidget cria uma janela de nível superior. Adicione o objeto QLabel nele.

  • Defina a legenda do rótulo como “hello world”.

  • Defina o tamanho e a posição da janela pelo método setGeometry ().

  • Entre no loop principal do aplicativo por 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()

O código acima produz a seguinte saída -

PyQt APIé uma grande coleção de classes e métodos. Essas classes são definidas em mais de 20 módulos. A seguir estão alguns dos módulos usados ​​com freqüência -

Sr. Não. Módulos e descrição
1

QtCore

Classes não-GUI principais usadas por outros módulos

2

QtGui

Componentes da interface gráfica do usuário

3

QtMultimedia

Aulas para programação multimídia de baixo nível

4

QtNetwork

Aulas de programação de rede

5

QtOpenGL

Classes de suporte OpenGL

6

QtScript

Classes para avaliar Scripts Qt

7

QtSql

Aulas para integração de banco de dados usando SQL

8

QtSvg

Classes para exibir o conteúdo de arquivos SVG

9

QtWebKit

Aulas para renderizar e editar HTML

10

QtXml

Classes para lidar com XML

11

QtAssistant

Suporte para ajuda online

12

QtDesigner

Classes para estender o Qt Designer

A API PyQt contém mais de 400 classes. oQObjectclasse está no topo da hierarquia de classes. É a classe base de todos os objetos Qt. Além disso,QPaintDevice class é a classe base para todos os objetos que podem ser pintados.

QApplicationclasse gerencia as configurações principais e o fluxo de controle de um aplicativo GUI. Ele contém o loop de evento principal dentro do qual eventos gerados por elementos de janela e outras fontes são processados ​​e despachados. Ele também lida com configurações de todo o sistema e do aplicativo.

QWidget classe, derivada das classes QObject e QPaintDevice, é a classe base para todos os objetos da interface do usuário. QDialog e QFrameclasses também são derivadas da classe QWidget. Eles têm seu próprio sistema de subclasse.

Os diagramas a seguir descrevem algumas classes importantes em sua hierarquia.

Aqui está uma lista de seleção de widgets usados ​​com frequência -

A seguir estão os Widgets comumente usados.

Sr. Não. Widgets e descrição
1

QLabel

Usado para exibir texto ou imagem

2

QLineEdit

Permite que o usuário insira uma linha de texto

3

QTextEdit

Permite ao usuário inserir texto multilinha

4

QPushButton

Um botão de comando para invocar a ação

5

QRadioButton

Permite escolher uma de várias opções

6

QCheckBox

Permite a escolha de mais de uma opção

7

QSpinBox

Permite aumentar / diminuir um valor inteiro

8

QScrollBar

Permite acessar o conteúdo de um widget além da abertura da tela

9

QSlider

Permite alterar o valor limite linearmente.

10

QComboBox

Fornece uma lista suspensa de itens para seleção

11

QMenuBar

Barra horizontal segurando objetos QMenu

12

QStatusBar

Normalmente, na parte inferior do QMainWindow, fornece informações de status.

13

QToolBar

Normalmente no topo de QMainWindow ou flutuante. Contém botões de ação

14

QListView

Fornece uma lista selecionável de itens em ListMode ou IconMode

15

QPixmap

Representação de imagem fora da tela para exibição no objeto QLabel ou QPushButton

16

QDialog

Janela modal ou não modal que pode retornar informações para a janela principal

A janela de nível superior de um aplicativo típico baseado em GUI é criado por QMainWindowobjeto widget. Alguns widgets, conforme listado acima, ocupam seu lugar designado nesta janela principal, enquanto outros são colocados na área de widget central usando vários gerenciadores de layout.

O diagrama a seguir mostra a estrutura QMainWindow -

O instalador PyQt vem com uma ferramenta de construção de GUI chamada Qt Designer. Usando sua interface simples de arrastar e soltar, uma interface GUI pode ser construída rapidamente sem a necessidade de escrever o código. No entanto, não é um IDE como o Visual Studio. Conseqüentemente, o Qt Designer não tem a facilidade de depurar e construir o aplicativo.

A criação de uma interface GUI usando o Qt Designer começa com a escolha de uma janela de nível superior para o aplicativo.

Você pode então arrastar e soltar os widgets necessários da caixa de widgets no painel esquerdo. Você também pode atribuir valor às propriedades do widget colocadas no formulário.

O formulário projetado é salvo como demo.ui. Este arquivo ui contém representação XML de widgets e suas propriedades no design. Este design é traduzido para o equivalente Python usando o utilitário de linha de comando pyuic4. Este utilitário é um wrapper para o módulo uic. O uso de pyuic4 é o seguinte -

pyuic4 –x demo.ui –o demo.py

No comando acima, a opção -x adiciona uma pequena quantidade de código adicional ao XML gerado para que ele se torne um aplicativo autônomo autoexecutável.

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_())

O script python resultante é executado para mostrar a seguinte caixa de diálogo -

O usuário pode inserir dados nos campos de entrada, mas clicar no botão Adicionar não gerará nenhuma ação, pois não está associado a nenhuma função. A reação à resposta gerada pelo usuário é chamada deevent handling.

Ao contrário de um aplicativo de modo de console, que é executado de maneira sequencial, um aplicativo baseado em GUI é orientado a eventos. Funções ou métodos são executados em resposta às ações do usuário, como clicar em um botão, selecionar um item de uma coleção ou clicar com o mouse etc., chamadosevents.

Os widgets usados ​​para construir a interface GUI agem como a fonte de tais eventos. Cada widget PyQt, que é derivado da classe QObject, é projetado para emitir 'signal'em resposta a um ou mais eventos. O sinal sozinho não executa nenhuma ação. Em vez disso, ele está 'conectado' a um 'slot'. O slot pode ser qualquercallable Python function.

No PyQt, a conexão entre um sinal e um slot pode ser realizada de diferentes maneiras. A seguir estão as técnicas mais comumente usadas -

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

Uma maneira mais conveniente de chamar um slot_function, quando um sinal é emitido por um widget, é a seguinte -

widget.signal.connect(slot_function)

Suponha que uma função deva ser chamada quando um botão é clicado. Aqui, o sinal clicado deve ser conectado a uma função chamável. Isso pode ser alcançado em qualquer uma das seguintes técnicas -

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

ou

button.clicked.connect(slot_function)

Exemplo

No exemplo a seguir, dois objetos QPushButton (b1 e b2) são adicionados na janela QDialog. Queremos chamar as funções b1_clicked () e b2_clicked () clicando em b1 e b2 respectivamente.

Quando b1 é clicado, o sinal clicked () é conectado à função b1_clicked ()

b1.clicked.connect(b1_clicked())

Quando b2 é clicado, o sinal clicked () é conectado à função b2_clicked ()

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

Exemplo

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()

O código acima produz a seguinte saída -

Resultado

Button 1 clicked
Button 2 clicked

Um widget GUI pode ser colocado dentro da janela do contêiner especificando suas coordenadas absolutas medidas em pixels. As coordenadas são relativas às dimensões da janela definidas pelo método setGeometry ().

Sintaxe setGeometry ()

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

No fragmento de código a seguir, a janela de nível superior com dimensões de 300 por 200 pixels é exibida na posição (10, 10) no 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()

UMA PushButton widget é adicionado na janela e colocado em uma posição 50 pixels à direita e 20 pixels abaixo da posição superior esquerda da janela.

este Absolute Positioning, no entanto, não é adequado pelos seguintes motivos -

  • A posição do widget não muda, mesmo se a janela for redimensionada.

  • A aparência pode não ser uniforme em dispositivos de exibição diferentes com resoluções diferentes.

  • A modificação no layout é difícil, pois pode ser necessário redesenhar todo o formulário.

A API PyQt fornece classes de layout para um gerenciamento mais elegante do posicionamento de widgets dentro do contêiner. As vantagens dos gerenciadores de layout sobre o posicionamento absoluto são -

  • Os widgets dentro da janela são redimensionados automaticamente.

  • Garante aparência uniforme em dispositivos de exibição com diferentes resoluções.

  • Adicionar ou remover widget dinamicamente é possível sem ter que redesenhar.

Aqui está a lista de classes que discutiremos uma a uma neste capítulo.

Sr. Não. Classes e descrição
1 QBoxLayout

A classe QBoxLayout alinha os widgets verticalmente ou horizontalmente. Suas classes derivadas são QVBoxLayout (para organizar widgets verticalmente) e QHBoxLayout (para organizar widgets horizontalmente).

2 QGridLayout

Um objeto de classe GridLayout se apresenta com uma grade de células organizadas em linhas e colunas. A classe contém o método addWidget (). Qualquer widget pode ser adicionado especificando o número de linhas e colunas da célula.

3 QFormLayout

QFormLayout é uma maneira conveniente de criar o formulário de duas colunas, onde cada linha consiste em um campo de entrada associado a um rótulo. Por convenção, a coluna esquerda contém o rótulo e a coluna direita contém um campo de entrada.

Aqui está a lista de widgets que discutiremos um por um neste capítulo.

Sr. Não Widgets e descrição
1 QLabel

Um objeto QLabel atua como um espaço reservado para exibir texto ou imagem não editável, ou um filme de GIF animado. Também pode ser usado como uma tecla mnemônica para outros widgets.

2 QLineEdit

O objeto QLineEdit é o campo de entrada mais comumente usado. Ele fornece uma caixa na qual uma linha de texto pode ser inserida. Para inserir texto de várias linhas, o objeto QTextEdit é necessário.

3 QPushButton

Na API PyQt, o objeto da classe QPushButton apresenta um botão que, quando clicado, pode ser programado para chamar uma determinada função.

4 QRadioButton

Um objeto de classe QRadioButton apresenta um botão selecionável com um rótulo de texto. O usuário pode selecionar uma das várias opções apresentadas no formulário. Esta classe é derivada da classe QAbstractButton.

5 QCheckBox

Uma caixa retangular antes do rótulo de texto aparece quando um objeto QCheckBox é adicionado à janela pai. Assim como QRadioButton, também é um botão selecionável.

6 QComboBox

Um objeto QComboBox apresenta uma lista suspensa de itens para seleção. É necessário um espaço mínimo de tela no formulário para exibir apenas o item atualmente selecionado.

7 QSpinBox

Um objeto QSpinBox apresenta ao usuário uma caixa de texto que exibe um número inteiro com o botão para cima / para baixo à direita.

8 Widget e sinal QSlider

O objeto da classe QSlider apresenta ao usuário uma ranhura sobre a qual uma alça pode ser movida. É um widget clássico para controlar um valor limitado.

9 QMenuBar, QMenu e QAction

Um QMenuBar horizontal logo abaixo da barra de título de um objeto QMainWindow é reservado para exibir objetos QMenu.

10 QToolBar

Um widget QToolBar é um painel móvel que consiste em botões de texto, botões com ícones ou outros widgets.

11 QInputDialog

Esta é uma caixa de diálogo pré-configurada com um campo de texto e dois botões, OK e Cancelar. A janela pai coleta a entrada na caixa de texto depois que o usuário clica no botão Ok ou pressiona Enter.

12 QFontDialog

Outro diálogo comumente usado, um widget seletor de fonte, é a aparência visual da classe QDialog. O resultado desta caixa de diálogo é um objeto Qfont, que pode ser consumido pela janela pai.

13 QFileDialog

Este widget é uma caixa de diálogo do seletor de arquivos. Ele permite que o usuário navegue pelo sistema de arquivos e selecione um arquivo para abrir ou salvar. O diálogo é invocado por meio de funções estáticas ou chamando a função exec_ () no objeto de diálogo.

14 QTab

Se um formulário tiver muitos campos para serem exibidos simultaneamente, eles podem ser organizados em páginas diferentes colocadas em cada guia de um widget com guias. O QTabWidget fornece uma barra de guias e uma área de página.

15 QStacked

O funcionamento de QStackedWidget é semelhante a QTabWidget. Também auxilia no uso eficiente da área cliente do Windows.

16 QSplitter

Se um formulário tiver muitos campos para serem exibidos simultaneamente, eles podem ser organizados em páginas diferentes colocadas em cada guia de um widget com guias. O QTabWidget fornece uma barra de guias e uma área de página.

17 QDock

Uma janela encaixável é uma subjanela que pode permanecer no estado flutuante ou pode ser anexada à janela principal em uma posição especificada. O objeto da janela principal da classe QMainWindow tem uma área reservada para janelas encaixáveis.

18 QStatusBar

O objeto QMainWindow reserva uma barra horizontal na parte inferior como a barra de status. É usado para exibir informações de status permanentes ou contextuais.

19 QList

A classe QListWidget é uma interface baseada em item para adicionar ou remover itens de uma lista. Cada item da lista é um objeto QListWidgetItem. ListWidget pode ser definido como multisselecionável.

20 QScrollBar

Um controle de barra de rolagem permite que o usuário acesse partes do documento que estão fora da área visível. Ele fornece um indicador visual da posição atual.

21 QCalendar

O widget QCalendar é um controle de seleção de data útil. Ele fornece uma visão baseada no mês. O usuário pode selecionar a data com o uso do mouse ou do teclado, sendo a data de hoje padrão.

UMA QDialogwidget apresenta uma janela de nível superior usada principalmente para coletar a resposta do usuário. Pode ser configurado para serModal (onde ele bloqueia sua janela pai) ou Modeless (a janela de diálogo pode ser ignorada).

A API PyQt tem vários widgets Dialog pré-configurados, como InputDialog, FileDialog, FontDialog, etc.

Exemplo

No exemplo a seguir, o atributo WindowModality da janela Dialog decide se é modal ou não modal. Qualquer botão na caixa de diálogo pode ser definido como padrão. A caixa de diálogo é descartada pelo método QDialog.reject () quando o usuário pressiona a tecla Escape.

Um PushButton em uma janela QWidget de nível superior, quando clicado, produz uma janela Dialog. Uma caixa de diálogo não possui controles para minimizar e maximizar em sua barra de título.

O usuário não pode relegar esta caixa de diálogo em segundo plano porque seu WindowModality está definido como 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()

O código acima produz a seguinte saída -

QMessageBoxé uma caixa de diálogo modal comumente usada para exibir alguma mensagem informativa e, opcionalmente, pedir ao usuário para responder clicando em qualquer um dos botões padrão nela. Cada botão padrão possui uma legenda predefinida, uma função e retorna um número hexadecimal predefinido.

Métodos e enumerações importantes associados à classe QMessageBox são fornecidos na tabela a seguir -

Sr. Não. Métodos e Descrição
1

setIcon()

Exibe um ícone predefinido correspondente à gravidade da mensagem

Questão

Em formação

Atenção

Crítico

2

setText()

Define o texto da mensagem principal a ser exibida

3

setInformativeText()

Exibe informações adicionais

4

setDetailText()

A caixa de diálogo mostra um botão Detalhes. Este texto aparece ao clicar nele

5

setTitle()

Mostra o título personalizado da janela

6

setStandardButtons()

Lista de botões padrão a serem exibidos. Cada botão está associado a

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.Retry 0x00080000

QMessageBox.Ignore 0x00100000

7

setDefaultButton()

Define o botão como padrão. Ele emite o sinal clicado se Enter for pressionado

8

setEscapeButton()

Define o botão a ser tratado como clicado se a tecla Escape for pressionada

Exemplo

No exemplo a seguir, clique no sinal do botão na janela de nível superior, a função conectada exibe a caixa de diálogo da caixa de mensagem.

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:")

A função setStandardButton () exibe os botões desejados.

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

O sinal buttonClicked () é conectado a uma função de slot, que identifica a legenda da fonte do sinal.

msg.buttonClicked.connect(msgbtn)

O código completo para o exemplo é o seguinte -

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()

O código acima produz a seguinte saída -

Um aplicativo GUI típico pode ter várias janelas. Os widgets com guias e empilhados permitem ativar uma janela por vez. No entanto, muitas vezes essa abordagem pode não ser útil, pois a visualização de outras janelas está oculta.

Uma maneira de exibir várias janelas simultaneamente é criá-las como janelas independentes. Isso é chamado de SDI (interface de documento único). Isso requer mais recursos de memória, pois cada janela pode ter seu próprio sistema de menu, barra de ferramentas, etc.

Os aplicativos MDI (Multiple Document Interface) consomem menos recursos de memória. As subjanelas são colocadas dentro do contêiner principal em relação umas às outras. O widget de contêiner é chamadoQMdiArea.

O widget QMdiArea geralmente ocupa o widget central do objeto QMainWondow. As janelas filho nesta área são instâncias da classe QMdiSubWindow. É possível definir qualquer QWidget como widget interno do objeto subWindow. As subjanelas na área MDI podem ser dispostas em cascata ou lado a lado.

A tabela a seguir lista métodos importantes da classe QMdiArea e da classe QMdiSubWindow -

Sr. Não. Métodos e Descrição
1

addSubWindow()

Adiciona um widget como uma nova subjanela na área MDI

2

removeSubWindow()

Remove um widget que é interno de uma subjanela

3

setActiveSubWindow()

Ativa uma subjanela

4

cascadeSubWindows()

Organiza subjanelas em MDiArea em cascata

5

tileSubWindows()

Organiza subjanelas em MDiArea em mosaico

6

closeActiveSubWindow()

Fecha a subjanela ativa

7

subWindowList()

Retorna a lista de subjanelas na Área MDI

8

setWidget()

Define um QWidget como um widget interno de uma instância QMdiSubwindow

O objeto QMdiArea emite o sinal subWindowActivated (), enquanto o sinal windowStateChanged () é emitido pelo objeto QMdisubWindow.

Exemplo

No exemplo a seguir, a janela de nível superior composta por QMainWindow tem um menu e MdiArea.

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

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

O sinal disparado () do menu está conectado à função windowaction ().

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

A nova ação do menu adiciona uma subjanela na área MDI com um título que possui um 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()

Os botões em cascata e lado a lado do menu organizam as subjanelas atualmente exibidas em cascata e lado a lado, respectivamente.

O código completo é o seguinte -

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()

O código acima produz a seguinte saída -

A provisão de drag and dropé muito intuitivo para o usuário. Ele é encontrado em muitos aplicativos de desktop onde o usuário pode copiar ou mover objetos de uma janela para outra.

A transferência de dados de arrastar e soltar baseada em MIME é baseada na classe QDrag. QMimeDataos objetos associam os dados ao seu tipo MIME correspondente. Ele é armazenado na área de transferência e usado no processo de arrastar e soltar.

As seguintes funções de classe QMimeData permitem que o tipo MIME seja detectado e usado convenientemente.

Testador Getter Normatizador Tipos MIME
hasText () texto() setText () texto / simples
hasHtml () html () setHtml () text / html
hasUrls () urls () setUrls () text / uri-list
hasImage () imageData () setImageData () imagem / *
hasColor () colorData () setColorData () aplicação / x-color

Muitos objetos QWidget suportam a atividade de arrastar e soltar. Aqueles que permitem que seus dados sejam arrastados têm setDragEnabled () que deve ser definido como verdadeiro. Por outro lado, os widgets devem responder aos eventos de arrastar e soltar para armazenar os dados arrastados para eles.

  • DragEnterEvent fornece um evento que é enviado para o widget de destino quando a ação de arrastar entra nele.

  • DragMoveEvent é usado quando a ação arrastar e soltar está em andamento.

  • DragLeaveEvent é gerado quando a ação arrastar e soltar deixa o widget.

  • DropEvent, por outro lado, ocorre quando a queda é concluída. A ação proposta do evento pode ser aceita ou rejeitada condicionalmente.

Exemplo

No código a seguir, o DragEnterEvent verifica se os dados MIME do evento contêm texto. Em caso afirmativo, a ação proposta para o evento é aceita e o texto é adicionado como um novo item no 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()

O código acima produz a seguinte saída -

PyQt API contém um elaborado sistema de classes para se comunicar com muitos bancos de dados baseados em SQL. Seu QSqlDatabase fornece acesso por meio de um objeto Connection. A seguir está a lista de drivers SQL disponíveis atualmente -

Sr. Não. Tipo e descrição do driver
1

QDB2

IBM DB2

2

QIBASE

Driver Borland InterBase

3

QMYSQL

Driver MySQL

4

QOCI

Driver de interface de chamada Oracle

5

QODBC

Driver ODBC (inclui Microsoft SQL Server)

6

QPSQL

Driver PostgreSQL

7

QSQLITE

SQLite versão 3 ou superior

8

QSQLITE2

SQLite versão 2

Exemplo

Uma conexão com um banco de dados SQLite é estabelecida usando o método estático -

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

Outros métodos da classe QSqlDatabase são os seguintes -

Sr. Não. Métodos e Descrição
1

setDatabaseName()

Define o nome do banco de dados com o qual a conexão é buscada

2

setHostName()

Define o nome do host no qual o banco de dados está instalado

3

setUserName()

Especifica o nome de usuário para conexão

4

setPassword()

Define a senha do objeto de conexão, se houver

5

commit()

Confirma as transações e retorna verdadeiro se for bem-sucedido

6

rollback()

Reverte a transação do banco de dados

7

close()

Fecha a conexão

A classe QSqlQuery tem a funcionalidade de executar e manipular comandos SQL. Ambos os tipos DDL e DML de consultas SQL podem ser executados. O método mais importante da classe é exec_ (), que recebe como argumento uma string contendo uma instrução SQL a ser executada.

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

O script a seguir cria um banco de dados SQLite sports.db com uma tabela de esportistas preenchida com 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()

A classe QSqlTableModel em PyQt é uma interface de alto nível que fornece modelo de dados editáveis ​​para leitura e gravação de registros em uma única tabela. Este modelo é usado para preencher um objeto QTableView. Ele apresenta ao usuário uma visualização rolável e editável que pode ser colocada em qualquer janela de nível superior.

Um objeto QTableModel é declarado da seguinte maneira -

model = QtSql.QSqlTableModel()

Sua estratégia de edição pode ser definida como qualquer uma das seguintes -

QSqlTableModel.OnFieldChange Todas as alterações serão aplicadas imediatamente
QSqlTableModel.OnRowChange As alterações serão aplicadas quando o usuário selecionar uma linha diferente
QSqlTableModel.OnManualSubmit Todas as alterações serão armazenadas em cache até que submitAll () ou revertAll () seja chamado

Exemplo

No exemplo a seguir, a tabela do esportista é usada como modelo e a estratégia é definida como -

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

   model.select()

A classe QTableView faz parte da estrutura Model / View no PyQt. O objeto QTableView é criado da seguinte maneira -

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

Este objeto QTableView e dois widgets QPushButton são adicionados à janela QDialog de nível superior. O sinal clicado () do botão adicionar é conectado a addrow () que executa insertRow () na tabela do modelo.

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

O Slot associado ao botão de exclusão executa uma função lambda que exclui uma linha, que é selecionada pelo usuário.

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

O código completo é o seguinte -

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_())

O código acima produz a seguinte saída -

Todos QWidgetas classes em PyQt são subclassificadas da classe QPaintDevice. UMAQPaintDeviceé uma abstração do espaço bidimensional que pode ser desenhado usando um QPainter. As dimensões do dispositivo de pintura são medidas em pixels a partir do canto superior esquerdo.

A classe QPainter executa pintura de baixo nível em widgets e outros dispositivos pintáveis, como impressora. Normalmente, ele é usado no evento de pintura do widget. oQPaintEvent ocorre sempre que a aparência do widget é atualizada.

O pintor é ativado chamando o método begin (), enquanto o método end () o desativa. No meio, o padrão desejado é pintado por métodos adequados, conforme listado na tabela a seguir.

Sr. Não. Métodos e Descrição
1

begin()

Começa a pintar no dispositivo de destino

2

drawArc()

Desenha um arco entre o ângulo inicial e final

3

drawEllipse()

Desenha uma elipse dentro de um retângulo

4

drawLine()

Desenha uma linha com as coordenadas do ponto final especificadas

5

drawPixmap()

Extrai o pixmap do arquivo de imagem e o exibe na posição especificada

6

drwaPolygon()

Desenha um polígono usando uma matriz de coordenadas

7

drawRect()

Desenha um retângulo começando na coordenada superior esquerda com a largura e altura fornecidas

8

drawText()

Mostra o texto nas coordenadas fornecidas

9

fillRect()

Preenche o retângulo com o parâmetro QColor

10

setBrush()

Define um estilo de pincel para pintura

11

setPen()

Define a cor, tamanho e estilo da caneta a ser usada para desenhar

Estilos QColor Predefinidos

Qt.NoBrush Sem padrão de pincel
Qt.SolidPattern Cor uniforme
Qt.Dense1Pattern Padrão de pincel extremamente denso
Qt.HorPattern Linhas horizontais
Qt.VerPattern Linhas verticais
Qt.CrossPattern Cruzando linhas horizontais e verticais
Qt.BDiagPattern Linhas diagonais para trás
Qt.FDiagPattern Linhas diagonais para frente
Qt.DiagCrossPattern Cruzando linhas diagonais

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

A cor personalizada pode ser escolhida especificando valores RGB, CMYK ou HSV.

Exemplo

O exemplo a seguir implementa alguns desses 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()

O código acima produz a seguinte saída -

o QClipboardA classe fornece acesso à área de transferência de todo o sistema que oferece um mecanismo simples para copiar e colar dados entre aplicativos. Sua ação é semelhante à classe QDrag e usa tipos de dados semelhantes.

A classe QApplication possui um método estático clipboard () que retorna a referência ao objeto clipboard. Qualquer tipo de MimeData pode ser copiado ou colado da área de transferência.

A seguir estão os métodos de classe da área de transferência que são comumente usados ​​-

Sr. Não. Métodos e Descrição
1

clear()

Limpa o conteúdo da área de transferência

2

setImage()

Copia QImage para a área de transferência

3

setMimeData()

Define dados MIME na área de transferência

4

setPixmap()

Copia o objeto Pixmap na área de transferência

5

setText()

Cópias QString na área de transferência

6

text()

Recupera texto da área de transferência

O sinal associado ao objeto da área de transferência é -

Sr. Não. Método e Descrição
1

dataChanged()

Sempre que os dados da área de transferência forem alterados

Exemplo

No exemplo a seguir, dois objetos TextEdit e dois botões de pressão são adicionados a uma janela de nível superior.

Para começar, o objeto da área de transferência é instanciado. O método Copy () do objeto textedit copia os dados para a área de transferência do sistema. Quando o botão Colar é clicado, ele busca os dados da área de transferência e os cola em outro objeto de texto.

QPixmapclasse fornece uma representação fora da tela de uma imagem. Ele pode ser usado como um objeto QPaintDevice ou pode ser carregado em outro widget, normalmente um rótulo ou botão.

Qt API tem outra classe semelhante QImage, que é otimizada para E / S e outras manipulações de pixel. Pixmap, por outro lado, é otimizado para ser exibido na tela. Ambos os formatos são interconvertíveis.

Os tipos de arquivos de imagem que podem ser lidos em um objeto QPixmap são os seguintes -

BMP Bitmap do Windows
GIF Formato de intercâmbio gráfico (opcional)
JPG Joint Photographic Experts Group
JPEG Joint Photographic Experts Group
PNG Gráficos Portáteis de Rede
PBM Bitmap portátil
PGM Graymap portátil
PPM Pixmap portátil
XBM Bitmap X11
XPM X11 Pixmap

Os métodos a seguir são úteis para lidar com o objeto QPixmap -

Sr. Não. Métodos e Descrição
1

copy()

Copia dados de pixmap de um objeto QRect

2

fromImage()

Converte o objeto QImage em QPixmap

3

grabWidget()

Cria um pixmap a partir do widget fornecido

4

grabWindow()

Crie pixmap de dados em uma janela

5

Load()

Carrega um arquivo de imagem como pixmap

6

save()

Salva o objeto QPixmap como um arquivo

7

toImage

Converte um QPixmap em QImage

O uso mais comum do QPixmap é exibir a imagem em uma etiqueta / botão.

Exemplo

O exemplo a seguir mostra uma imagem exibida em um QLabel usando o método setPixmap (). O código completo é o seguinte -

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()

O código acima produz a seguinte saída -