PyQt 10 – QCheckBox e QRadioButton: checando as opções

maio 29th, 2010 by rudsonalves Leave a reply »

Neste artigo vou apresentar as widgets QCheckBox e QRadioButtun. Estas widgets geralmente são usadas para selecionar opções ou configurar características em um aplicativo, diferindo apenas quanto a múltipla seleção, possível epenas em grupos de QCheckBox.

Obviamente, o seu uso deve respeitar a sua forma de seleção. Por exemplo, considere um diálogo para pesquisar o tipo de filmes de interesse de um usuário. Este tipo de seleção pode ter múltiplas escolhas, e por isto deve ser feita com a widget QCheckBox.

Em um segundo diálogo onde se deseja que o usuário escolha um navegador padrão para o seu sistema, apenas um navegador deve ser selecionado como o padrão. Ai a widget adequada é a QRadioButton para o serviço.

QCheckBox: Sinais

Além de herdar os sinais da classe QAbstractButton (veja a descrição dos sinais no artigo anterior: PyQt 09 – QPushButton, apertando os botões, o QCheckBox possui ainda o sinal exclusivo, descrito na tabela abaixo:

Sinal Descrição
stateChanged(Int) Este sinal é emitido se o estado do CheckBox mudar de checado para não checado e vice-versa.

O inteiro de retorno do método acima é 2 (Qt.Checked), se o CheckBox for checado, e 0 (Qt.Unchecked) em caso contrário. Outro retorno possível é o 1 (Qt.PartiallyChecked), quando um item é parcialmente checado, usado em itens em modelos hierárquicos, como a seleção de alguns subdiretórios, arquivos em uma pasta. a tabela a seguir apresenta estes valores:

Constante Valor Descrição
Qt.Unchecked 0 o item não está checado
Qt.PartiallyChecked 1 o item está parcialmente checado, usado em itens hierárquicos (diretórios, …)
Qt.Checked 2 o item está checado

O código abaixo gera uma mensagem simples para cada CheckBox clicado, no diálogo de seleção apresentado acima.

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
41
42
43
44
45
46
47
48
#!/bin/env python
# -*- coding: iso-8859-1 -*-
#
# por Rudson R. Alves
#
 
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from Dialogo_TiposdeFilmes import *
 
 
class CheckBoxDialog(QDialog, Ui_Dialog_TiposFilmes):
  def __init__(self, parent = None):
    super(CheckBoxDialog, self).__init__(parent)
    self.setupUi(self)
 
  @pyqtSignature("int")
  def on_checkBox_0_stateChanged(self, status):
    print u'CheckBox %s status é:%d' % (self.checkBox_0.text(), status)
 
  @pyqtSignature("int")
  def on_checkBox_1_stateChanged(self, status):
    print u'CheckBox %s status é:%d' % (self.checkBox_1.text(), status)
 
  @pyqtSignature("int")
  def on_checkBox_2_stateChanged(self, status):
    print u'CheckBox %s status é:%d' % (self.checkBox_2.text(), status)
 
  @pyqtSignature("int")
  def on_checkBox_3_stateChanged(self, status):
    print u'CheckBox %s status é:%d' % (self.checkBox_3.text(), status)
 
  @pyqtSignature("int")
  def on_checkBox_4_stateChanged(self, status):
    print u'CheckBox %s status é:%d' % (self.checkBox_4.text(), status)
 
  @pyqtSignature("int")
  def on_checkBox_5_stateChanged(self, status):
    print u'CheckBox %s status é:%d' % (self.checkBox_5.text(), status)
 
  @pyqtSignature("int")
  def on_checkBox_6_stateChanged(self, status):
    print u'CheckBox %s status é:%d' % (self.checkBox_6.text(), status)
 
app = QApplication(sys.argv)
dlg = CheckBoxDialog()
dlg.exec_()

O código Python do diálogo e arquivo ui, criado pelo Qt Designer, podem ser baixados no arquivo pyqt-10.zip.

Selecionando e removendo a seleção de cada opção do diálogo criado, irá gerar a saída no console abaixo:

rudson@khelben:$ ./qcheckbox-01 
CheckBox Ação status é:2
CheckBox Ação status é:0
CheckBox Comédia status é:2
CheckBox Comédia status é:0
CheckBox Comédia Romântica status é:2
CheckBox Comédia Romântica status é:0
CheckBox Ficção status é:2
CheckBox Ficção status é:0
CheckBox Romance status é:2
CheckBox Romance status é:0
CheckBox Suspence status é:2
CheckBox Suspence status é:0
CheckBox Terror status é:2
CheckBox Terror status é:0

O código anterior não é dos mais inteligentes, embora dê conta do recado, é muito extenso para fazer tão pouco. Um código muito mais eficiente e elegante é apresentado a seguir:

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
#!/bin/env python
# -*- coding: iso-8859-1 -*-
#
# por Rudson R. Alves
#
 
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from Dialogo_TiposdeFilmes import *
 
 
class CheckBoxDialog(QDialog, Ui_Dialog_TiposFilmes):
  def __init__(self, parent = None):
    super(CheckBoxDialog, self).__init__(parent)
    self.setupUi(self)
 
    self.connect(self.checkBox_0, SIGNAL("stateChanged(int)"),self.CheckBox_stateChanged)
    self.connect(self.checkBox_1, SIGNAL("stateChanged(int)"),self.CheckBox_stateChanged)
    self.connect(self.checkBox_2, SIGNAL("stateChanged(int)"),self.CheckBox_stateChanged)
    self.connect(self.checkBox_3, SIGNAL("stateChanged(int)"),self.CheckBox_stateChanged)
    self.connect(self.checkBox_4, SIGNAL("stateChanged(int)"),self.CheckBox_stateChanged)
    self.connect(self.checkBox_5, SIGNAL("stateChanged(int)"),self.CheckBox_stateChanged)
    self.connect(self.checkBox_6, SIGNAL("stateChanged(int)"),self.CheckBox_stateChanged)
 
  def CheckBox_stateChanged(self):
    checkbox = self.sender()
    print u'CheckBox %s status é:%s' % (checkbox.text(), checkbox.isChecked())
 
app = QApplication(sys.argv)
dlg = CheckBoxDialog()
dlg.exec_()

A ideia é bem simples, o segredo está em redirecionar os sinais stateChanged(int) dos diferentes QCheckBox para uma única função, CheckBox_stateChanged, linhas 18 a 24. O CheckBox selecionado é recuperado pela função sender(), que retorna a widget que disparou o sinal, para a variável checkbox, na linha 27.

Obs: Imaginei que a função sender() fosse herdada de uma classe como QWidget, ou fizesse parte do escopo das classes QDialogo, QMainWindow, entre outras. No entanto não o encontrei. Se alguém tiver alguma informação, ela poderia ser bem instrutiva aqui.

QRadioButton: Sinais

O widget QRadioButton não possui nenhum sinal específico, herdando todos os sinais necessários ao seu funcionamento da classe QAbstractButton, que, como dito anteriormente, já foram apresentados no artigo anterior: PyQt 09 – QPushButton, apertando os botões.

O código a seguir mostra o funcionamento do diálogo com os QPushButton, mostrado no início deste texto, usando os mesmos princípios do 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
#!/bin/env python
# -*- coding: iso-8859-1 -*-
#
# por Rudson R. Alves
#
 
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from Dialogo_Navegador import *
 
 
class CheckBoxDialog(QDialog, Ui_Dialog_Navegador):
  def __init__(self, parent = None):
    super(CheckBoxDialog, self).__init__(parent)
    self.setupUi(self)
 
    self.connect(self.radioButton_0, SIGNAL("clicked(bool)"),self.RadioButton_clicked)
    self.connect(self.radioButton_1, SIGNAL("clicked(bool)"),self.RadioButton_clicked)
    self.connect(self.radioButton_2, SIGNAL("clicked(bool)"),self.RadioButton_clicked)
    self.connect(self.radioButton_3, SIGNAL("clicked(bool)"),self.RadioButton_clicked)
    self.connect(self.radioButton_4, SIGNAL("clicked(bool)"),self.RadioButton_clicked)
 
  def RadioButton_clicked(self):
    radiobutton = self.sender()
    print u'RadioButton %s status foi selecionado' % radiobutton.text()
 
 
app = QApplication(sys.argv)
dlg = CheckBoxDialog()
dlg.exec_()

A principal diferença entre este código e o anterior, está no sinal utilizado para checar o item selecionado no diálogo, que neste último foi o sinal “clicked()”.

Embora seja bem funcional, não é de praxe fazer o código desta forma. QCheckBoxs geralmente são agrupados em grupos definidos pela classe QButtonGroup ou QGroupBox. Mesmo os QCheckBox e os QPushButton podem ser agrupados assim. Mas isto fica para o próximo texto.

Advertisement

3 comments

  1. Willian Henrique disse:

    Cara muito show de bola ….
    Muito útil parabéns

    abraços

  2. Oraculum disse:

    Não sei porque mais comigo não funcionou o self.checkBox_3.text() então eu fiz assim:

    if self.ui.checkboxAlarms.isChecked():
    alarms = 1
    else:
    alarms = 0

    é bem mais código mas foi a única maneira que achei de usar o bool no sqlite, pois o isChecked() retorna true e false de acordo com o estado do checkbox.

Deixe uma resposta