- 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
O QComboBox é uma widget muito versátil que combina uma lista e um botão de forma bem compacta. O elemento selecionado é sempre apresentado, podendo ser ele tanto uma string como um pixmap.
Neste texto vou apresentar a carga, seleção, edição, bem como outras habilidades interessantes da widget QComboBox.
Neste texto vou construir um diálogo hipotético para um simples cadastro de vendedores, onde vendedores naturais de um estado são designados a operarem em uma região (falta de imaginação não…). O diálogo é apresentado na figura abaixo:
O código e diálogo usado neste texto pode ser baixado no link: pyqt-12.zip
O seu código foi gerado no Qt Designer, conectando os botões Ok e Cancelar aos sinais accept() e reject() do diálogo. O código a seguir servirá de base para o desenvolvimento deste diálogo:
#!/bin/env python
# -*- coding: iso-8859-1 -*-
#
# Hello World por Rudson R. Alves
#
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from vendedor import Ui_Dialog
class ComboBoxDialog(QDialog, Ui_Dialog):
def __init__(self, nome = None, parent = None):
super(ComboBoxDialog, self).__init__(parent)
self.setupUi(self)
if nome:
self.lineEdit_vendedor.setText(nome)
estados = [u'Acre', u'Alagoas', u'Amapá', u'Amazonas', \
u'Bahia', u'Ceará', u'Distrito Federal', \
u'Espírito Santo', u'Goiás', u'Maranhão', \
u'Mato Grosso', u'Mato Grosso do Sul', \
u'Minas Gerais', u'Pará', u'Paraíba', u'Paraná', \
u'Pernambuco', u'Piauí', u'Rio de Janeiro', \
u'Rio Grande do Norte', u'Rio Grande do Sul', \
u'Rondônia', u'Roraima', u'Santa Catarina',
u'São Paulo', u'Sergipe', u'Tocantins']
self.comboBox_estado.addItems(estados)
def accept(self):
print u'\nSaída'
print u'Estado: %s' % self.comboBox_estado.currentText()
print u'Índice: %d' % self.comboBox_estado.currentIndex()
print u'Região: %s' % self.comboBox_regiao.currentText()
print u'Índice: %d' % self.comboBox_regiao.currentIndex()
QDialog.accept(self)
app = QApplication(sys.argv)
dlg = ComboBoxDialog(u'Alberto Roberto')
dlg.exec_()
O QComboBox região foi preenchido durante a construção do diálogo no Qt Designer, no entanto, o QComboBox dos estados é preenchido com os estados contidos na lista estados, definida na linha 20. O preenchimento é feito com o método addItems, na linha 30, que recebe como argumento uma lista de strings, ou mais precisamente, uma QStringList.
Outro método que poderia fazer o mesmo é o addItem, com o auxílio de um loop. O addItem ainda comporta a entrada de objetos QIcon, para criar listas de icones no ComboBox.
A função accept(self), declarada na linha 33, redefine a saída padrão do diálogo, imprimido os conteúdos das seleções dos diálogos, índice e conteúdo. Isto é uma redefinição do método padrão accept, herdada da classe QDialog, que termina por ser invocada na linha 39.
Sinais
Como de praxe, apresento a seguir os sinais suportados pela classe QComboBox.
[TABLE=31]
Observe que os sinais currentIndexChanged(int) e currentIndexChanged(QString), são o mesmo sinal. Não é possível capiturar ambos simultaneamente. Um código como o seguinte:
@pyqtSignature("QString")
def on_comboBox_regiao_currentIndexChanged(self, text):
print u'Região texto alterado: %s' % text
@pyqtSignature("int")
def on_comboBox_regiao_currentIndexChanged(self, index):
print u'Região índice alterado: %s' % index
retornará apenas o índice do elemento selecionado, uma vez que a definição na linha 46 será compreendida pelo Python como uma redefinição do método on_comboBox_regiao_currentIndexChanged.
O mesmo acontece com o par de sinais activated(int) e activated(QString), e o par highlighted(int) e highlighted(QString).
Implementando Sinais
Inicialmente vou implementar os sinais currentIndexChanged(QString), dos dois ComboBox, fazendo com que uma mensagem seja impressa, mostrando a string selecionada. Isto é feito adicionando as linhas abaixo, a partir da linha 33 do código original:
@pyqtSignature("QString")
def on_comboBox_estado_currentIndexChanged(self, text):
print u'Estado texto alterado: %s' % text
@pyqtSignature("QString")
def on_comboBox_regiao_currentIndexChanged(self, text):
print u'Região texto alterado: %s' % text
Ao selecionar os diferentes elementos dos ComboBox região e estado, seus conteúdos serão impressos, gerando uma saída semelhante à abaixo, no console:
./dialog_vendedor Estado texto alterado: Acre Estado texto alterado: Alagoas Estado texto alterado: Amapá Estado texto alterado: Amazonas Estado texto alterado: Bahia Região texto alterado: Sul Região texto alterado: Nordeste Região texto alterado: Sudeste Saída Estado: Bahia Índice: 4 Região: Sudeste Índice: 3
Neste teste naveguei com o TAB, pelos elementos do diálogo, selecionando o estado e depois a região com as teclas direcionais. As últimas 5 linhas são impressas após pressionar o botão Ok do diálogo, ou a tecla ENTER.
Na próxima implementação, adiciono o sinal activated ao ComboBox estado apenas. As linhas abaixo fazem a implementação:
@pyqtSignature("QString")
def on_comboBox_estado_activated(self, text):
print u'Estado texto activated: %s' % text
Como explicado na tabela de sinais acima, esta sinal será emitido sempre que um estado for selecionado. Aparentemente isto parece replicar o sinal currentIndexChanged, no entanto, esta sinal será emitido mesmo que o mesmo estado seja selecionado novamente. Experimente executar o código e fazer o seguinte procedimento:
- Pressione TAB para mudar para o ComboBox estado;
- em seguida pressione a letra ‘G‘. Isto irá selecionar o estado de ‘Goiás‘, o primeiro com a letra ‘G‘;
- em seguida, usando o mouse, pressione no ComboBox estado e selecione novamente o estado de Goiás
observe que isto irá emitir um novo sinal activated, mas não o currentIndexChanged, uma vez que o texto não foi alterado. Veja a saída no console, abaixo:
./dialog_vendedor Estado texto alterado: Acre Estado texto alterado: Goiás Estado texto activated: Goiás Estado texto activated: Goiás
Nas próximas linhas adiciono o código para habilitar a edição no ComboBox região. Para isto será necessário usar o CheckBox região, para mudar o estado Editable do ComboBox. As linhas a seguir fazem isto:
@pyqtSignature("int")
def on_checkBox_regiao_stateChanged(self, status):
if status == Qt.Checked:
self.comboBox_regiao.setEditable(True)
else:
self.comboBox_regiao.setEditable(False)
@pyqtSignature("QString")
def on_comboBox_regiao_editTextChanged(self, text):
print u'Texto editado: %s' % text
Na linha 57 é implementado o sinal editTextChanged, no ComboBox região, para verificar alterações nos elementos deste objeto. O console baixo mostra o que acontece quando a string do ComboBox é editada, conforme a figura do diálogo, no inicio deste texto:
./dialog_vendedor Estado texto alterado: Acre O elemento 0 foi highlighted... O elemento 5 foi highlighted... Estado texto alterado: Ceará Estado texto activated: Ceará Região texto alterado: Nordeste Texto editado: Nordeste Texto editado: Nordeste é Texto editado: Nordeste é Texto editado: Nordeste é q Texto editado: Nordeste é qu Texto editado: Nordeste é que Texto editado: Nordeste é quen Texto editado: Nordeste é quent Texto editado: Nordeste é quente Saída Estado: Ceará Índice: 5 Região: Nordeste é quente Índice: 2
Alguns Comentários e Recomendações
Não tenho dedicado muito espaço aos métodos das classes apresentadas, me limitando mais especificamente aos sinais gerados pelos widgets. Bom isto se deve a dois motivos muito simples:
- são muitos métodos: Se fosse apresentar todos os métodos, este texto mais se aproximaria de uma tradução da documentação do PyQt. Não que a ideia não seja interessante, mas reconheço que não sou o indivíduo mais indicado para este trabalho;
- é necessário ler a documentação: por mais que dê exemplos e apresente alguns aspectos deste bind (PyQt) de certo não alcançarei todas as nuances das classes apresentadas. Por isto é fortemente recomendado a leitura da documentação oficial.
No entanto vou listar alguns métodos bastantes uteis dos ComboBox, mas nem de longe alcançareis todos:
[TABLE=32]
Como disse estes são apenas alguns métodos e com apenas algumas de suas opções. Métodos como o findText ainda suportam as flags: Qt.MatchFlags flags = Qt.MatchExactly | Qt.MatchCaseSensitive, não apresentadas na tabela acima.
Já pensou em publicar um livro sobre PyQt4, seus posts já dão um excelente material inicial, tenho certeza que editoras como a novatec se ficariam interessados pelo assunto.
Nem chegou perto Willian. PyQt é um universo bem maior do que abordei. Tão maior que entre um texto e outro, sempre fico me perguntando “e agora, qual será o próximo?”, dado a diversidade de tópicos disponíveis. Mas valeu a confiança.