- 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
Deste artigo em diante, vou fazer fazer uma série de apresentações de 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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | #!/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:
Tab 01: Sinais do QLabel
| Sinal | Descrição |
|---|---|
| linkActivated(QString url) | este sinal é emitido quando o usuário clica sobre um link passado no QLabel |
| linkHovered(QString url) | este sinal é emitido quando o mouse entra e sai de cima de um link passado no QLabel |
O código abaixo mostra os dois sinais em ação:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | #!/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: <a href=\"http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qlabel.html\">QLabel</a></em>") 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.
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #!/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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #!/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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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: <a href=\"http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/qlabel.html\">QLabel</a></em>", 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("<signal signature>") def on_<nome do objeto que gerou o sinal>_<nome do sinal>(<parâmetros do sinal>);
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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | #!/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…
<< Instalando MySql + Apache + Php + WordPress PyQt 08 – QLineEdit e mais Qt Designer >>
You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.









One comment
Rodrigo