- PyQt 01 – O Primeiro Programa
- PyQt 02 – Criando uma caixa de mensagem
- PyQt 03 – Diálogos com QMessageBox
- PyQt 04 – Diálogos com QInputDialog
- PyQt 05 – Diálogo QFileDialog
- PyQt 06 – Mais diálogos
- PyQt 07 – QLabel e Qt Designer
- PyQt 08 – QLineEdit e mais Qt Designer
- PyQt 09 – QPushButton, apertando os botões
- PyQt 10 – QCheckBox e QRadioButton: checando as opções
- PyQt 11 – QButtonGroup e QGroupBox: mais opções
- PyQt 12 – QComboBox
- PyQt 13 – QSpinBox, QProgressBar e + sinais
- PyQt 14 – QNetwork, baixando arquivos
Deste artigo em diante, apresentarei diferentes Widgets da Qt, iniciando por Widgets básicas como a QLabel, QLineEdit, QpushButton, entre outras. Para deixar o trabalho mais fluido e não ter que me preocupar com a construção e modelagem das janelas de diálogos, vou aproveitar e fazer uma breve introdução do aplicativo Designer, um construtor de GUI (Graphical User Interface) bem simples, oferecida juntamente com a biblioteca Qt.
Não é intenção deste texto ser um tutorial do uso do Qt Designer, ainda porque existem muitos outros artigos na rede que se propõem a isto. O foco aqui será mais no desenvolvimento do aplicativo, como as conexões dos sinais e o uso de alguns métodos e atributos interessantes para este desenvolvimento.
Widget QLabel
A widget QLabel permite apresentar um texto ou uma imagem. Para se familiarizar com as widgets do Qt é interessante sempre verificar a árvore de herança da classe apresentada. Isto deve acrescentar no momento de determinar os métodos, atributos e sinais relevantes em uma classe, bem como os herdados. A árvore de herança da classe QLabel é apresentada a seguir:
QLabel -> QFrame -> QWidget -> QObject QPaintDevice
Criar o costume de conhecer as classes herdadas pelos widgets, irá render um conhecimento mais consistente do toolkit Qt, essencial para desenvolver um bom aplicativo.
Para prosseguir com a investigação do QLabel, crie um diálogo simples com apenas dois labels como no código abaixo:
#!/bin/env python
#
# Hello World por Rudson R. Alves
#
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyDialog(QDialog):
def __init__(self, parent = None):
super(MyDialog, self).__init__(parent)
label1 = QLabel("<h2>Hello</h2>")
label2 = QLabel("<h1 style=\"color: #0000FF\">World...</h1>")
vbox = QVBoxLayout()
vbox.addWidget(label1)
vbox.addWidget(label2)
self.setLayout(vbox)
app = QApplication(sys.argv)
dlg = MyDialog()
dlg.exec_()
Este código deve gerar o diálogo abaixo:
A widget QLabel aceita como entrada uma string simples, rick text, tags html e uma QString (string com caracteres unicode).
Sinais emitidos pela QLabel
A widget QLabel emite apenas dois sinais:
[TABLE=22]
O código abaixo mostra os dois sinais em ação:
#!/bin/env python
# -*- coding: iso-8859-1 -*-
#
# qlable_url por Rudson R. Alves
#
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyDialog(QDialog):
def __init__(self, parent = None):
super(MyDialog, self).__init__(parent)
self.link_label = QLabel("Passe o mouse sobre o link: QLabel")
self.msg_label = QLabel("")
vbox = QVBoxLayout()
vbox.addWidget(self.link_label)
vbox.addWidget(self.msg_label)
self.connect(self.link_label, SIGNAL("linkActivated(QString)"), self.Activated)
self.connect(self.link_label, SIGNAL("linkHovered(QString)"), self.Hovered)
self.setLayout(vbox)
def Activated(self, url):
print "linkActivated..."
QDesktopServices().openUrl(QUrl(url))
def Hovered(self, url):
print "linkHovered..."
if self.msg_label.text() == "":
self.msg_label.setText("Click no link para abrir no browser.\nClick com o botão direito para copiar o link.")
else:
self.msg_label.setText("")
app = QApplication(sys.argv)
dlg = MyDialog()
dlg.exec_()
Este código vai gera um diálogo simples com uma mensagem. A segunda mensagem aparecerá ao passar o mouse sobre o link QLabel. Clicando sobre o link o browser padrão de seu sistema deve abrir com a página da documentação completa do QLabel, direto da página oficial do PyQt.
A mágica é feita nas linhas 22 e 23, onde os sinais emitidos pelo QLabel link_label são conectados aos slots (neste caso métodos da classe MyDialog) Activated e Hovered. A conexão é feita pelo comando connect seguindo a sintaxe:
self.connect(Objeto, SIGNAL("Sinal emitido pelo Objeto"), Slot a ser conectado)
O Slot a ser conectado pode ser tanto um método de um dos objetos de sua janela (geralmente chamado de slot), ou um método criado em sua classe.
O sinal emitido pelos objetos podem ser conhecido investigando a documentação do PyQt. Basta pesquisar a classe desejada e verificar os seus sinais emitidos. Em alguns casos, o sinal desejado pode estar em alguma das classes herdadas, por isto não deixe de ver suas heranças.
Designer
O aplicativo Qt Designer é distribuído juntamente com a toolkit Qt, sobre o nome designer. Ele é um poderoso editor de interface gráfica para usuário, no entanto trabalha apenas com a biblioteca Qt.
Em um terminal, execute o comando designer para abri o construtor de GUI. A tela inicial é semelhante a apresentada a seguir:
Para este primeiro contado, vou construir o mesmo diálogo anterior. Para isto selecione um diálogo sem botões (Dialog without buttons). Isto deve criar um diálogo vazio.
Primeiro altere o nome do diálogo, editando o campo ObjectName, na caixa de Propriedades (Property) no centro à esquerda, como mostra a figura a seguir:
Agora altere o título que aparece na parte superior do diálogo, editando o campo windowTitle,
Para terminar o diálogo, falta adicionar os dois QLabels: link_label e msg_label, como feito no código anterior. Para isto, role a barra de rolagem da caixa Widget Box, à esquerda do Designer, até aparecer a seção Display Widgets. Logo no início desta seção você vai encontrar a widget QLabel, com o nome Label.
Agarre a widget QLabel na Widget Box e a solte sobre o diálogo. Repita o processo para a segunda QLabel. Seu diálogo deve ficar com a aparência abaixo:
Em seguida de um duplo click sobre o primeiro QLabel para alterar o seu texto, ou edite a propriedade text, com o texto “Passe o mouse sobre o link: <a href=\”http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qlabel.html\”>QLabel</a></em>”.
Repita o processo para o segundo QLabel, com o texto: “Click no link para abrir no browser.\nClick com o botão direito para copiar o link.”
Para terminar, resta ainda aplicar o Layout Vertical. Clique sobre o diálogo (atenção para não selecionar nenhum dos QLabels) e em seguida clique no botão Lay Out Vertically, circulado em verde na figura abaixo:
Isto irá deixar o diálogo com a aparência abaixo:
Selecione o primeiro QLabel para altera o seu nome (propriedade objectName) para link_label e o segundo QLabel para msg_label.
Agora o diálogo está pronto. Salve-o com o nome “link_qlabel.ui“. O Python não consegue trabalhar diretamente com este arquivo UI. É necessário criar um módulo a partir deste arquivo com o comando pyuic4.
pyuic4 -o link_qlabel.py link_qlabel.ui
Isto irá gerar um módulo link_qlabel.py com a classe Ui_QLabel_url_Dialog, com dois métodos: setupUi e retranslateUi. Agora crie o código para o novo aplicativo com o conteúdo a seguir:
#!/bin/env python
# -*- coding: iso-8859-1 -*-
#
# Hello World por Rudson R. Alves
#
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from link_qlabel import *
class MyDialog(QDialog, Ui_QLabel_url_Dialog):
def __init__(self, parent = None):
super(MyDialog, self).__init__(parent)
self.setupUi(self)
app = QApplication(sys.argv)
dlg = MyDialog()
dlg.exec_()
Este código apenas permite abrir o diálogo, mas ainda não tem nenhuma funcionalidade. Em seguida adicione as conexões aos sinais como no código anterior.
#!/bin/env python
# -*- coding: iso-8859-1 -*-
#
# Hello World por Rudson R. Alves
#
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from link_qlabel import *
class MyDialog(QDialog, Ui_QLabel_url_Dialog):
def __init__(self, parent = None):
super(MyDialog, self).__init__(parent)
self.setupUi(self)
self.connect(self.link_label, SIGNAL("linkActivated(QString)"), self.Activated)
self.connect(self.link_label, SIGNAL("linkHovered(QString)"), self.Hovered)
def Activated(self, url):
print "linkActivated..."
QDesktopServices().openUrl(QUrl(url))
def Hovered(self, url):
print "linkHovered..."
if self.msg_label.text() == "":
self.msg_label.setText("Click no link para abrir no browser.\nClick com o botão direito para copiar o link.")
else:
self.msg_label.setText("")
app = QApplication(sys.argv)
dlg = MyDialog()
dlg.exec_()
O uso do Qt Designer deixa o seu código bem mais limpo, uma vez que não há a necessidade de criar todos os elementos do diálogo, como os labels, vbox, … Mas as habilidades do Qt Designer vai bem além de apenas simplificar o trabalho na criação das janelas. Explorar tudo é algo extenso e nem mesmo acredito que saiba tando assim para apresentar.
Uma destas habilidades que gosto muito de utilizar é a conexão de sinais automática, que despolui muito o código. Mas antes de uma olhada na classe Ui_QLabel_url_Dialog, criada pelo pyuic4 ao processar o arquivo ui gerado pelo Qt Designer:
class Ui_QLabel_url_Dialog(object):
def setupUi(self, QLabel_url_Dialog):
QLabel_url_Dialog.setObjectName("QLabel_url_Dialog")
QLabel_url_Dialog.resize(335, 99)
self.verticalLayout = QtGui.QVBoxLayout(QLabel_url_Dialog)
self.verticalLayout.setObjectName("verticalLayout")
self.link_label = QtGui.QLabel(QLabel_url_Dialog)
self.link_label.setObjectName("link_label")
self.verticalLayout.addWidget(self.link_label)
self.msg_label = QtGui.QLabel(QLabel_url_Dialog)
self.msg_label.setObjectName("msg_label")
self.verticalLayout.addWidget(self.msg_label)
self.retranslateUi(QLabel_url_Dialog)
QtCore.QMetaObject.connectSlotsByName(QLabel_url_Dialog)
def retranslateUi(self, QLabel_url_Dialog):
QLabel_url_Dialog.setWindowTitle(QtGui.QApplication.translate("QLabel_url_Dialog", "QLabel Links Signals", None, QtGui.QApplication.UnicodeUTF8))
self.link_label.setText(QtGui.QApplication.translate("QLabel_url_Dialog", "Passe o mouse sobre o link: QLabel", None, QtGui.QApplication.UnicodeUTF8))
self.msg_label.setText(QtGui.QApplication.translate("QLabel_url_Dialog", "Click no link para abrir no browser.\nClick com o botão direito para copiar o link.", None, QtGui.QApplication.UnicodeUTF8))
Como pode ser visto, o método setupUi é quem cria os elementos do diálogo, alinhando-os e atribuindo-lhe as informações editadas no Qt Designer. O método retranslateUi translada o texto para UTF-8 e preenche as QLabels com os textos padrões. Mas quem faz a mágica a que estou interessado em discutir aqui é o método connectSlotsByName, da classe QMetaObject, chamado na linha 15 da classe acima.
Este método pesquisa recursivamente os objetos e objetos filhos, conectando os sinais aos slots que possuem a seguinte forma:
@pyqtSignature("")
def on__();
O decorador “@pyqtSignature” não é obrigatório, mas garante que o sinal capturado será sempre o desejado. Ele deve passar a assinatura do sinal a ser capturado. Isto pode ser conhecido consultando o sinal da widget desejada, neste caso os sinais do QLabel. Estes sinais foram apresentados acima, e suas assinaturas são idênticas, retornando sempre uma QString.
Fazendo mais algumas mudanças ao código, substituindo as conexões e redefinindo os métodos Activated e Hovered para serem conectados automaticamente pelo connectSlotsByName, o código pode ficar ainda mais simples:
#!/bin/env python
# -*- coding: iso-8859-1 -*-
#
# Hello World por Rudson R. Alves
#
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from link_qlabel import *
class MyDialog(QDialog, Ui_QLabel_url_Dialog):
def __init__(self, parent = None):
super(MyDialog, self).__init__(parent)
self.setupUi(self)
@pyqtSignature("QString")
def on_link_label_linkActivated(self, url):
print "linkActivated %s" % url
QDesktopServices().openUrl(QUrl(url))
@pyqtSignature("QString")
def on_link_label_linkHovered(self, url):
print "linkHovered %s" % url
if self.msg_label.text() == "":
self.msg_label.setText("Click no link para abrir no browser.\nClick com o botão direito para copiar o link.")
else:
self.msg_label.setText("")
app = QApplication(sys.argv)
dlg = MyDialog()
dlg.exec_()
Além da uma mensagem, a url agora será impressa a cada sinal emitido pelo QLabel link_label.
Os códigos desenvolvidos neste texto podem ser baixados pelo link: pyqt-07.zip.
Bom até o próximo…
Parabéns pela série de posts sobre PyqT, ESTÃO EXCELENTES!
Muito Obrigado, estou aprendendo muito!
Um abraço!