QT, al contrario de otras librerias centradas en el desarrollo de interfaces gráficas de usuario, no implementa un widget que permita agrupar una lista de radio buttons. Crear un nuevo Widget que permita esto, no es muy complicado. A continuación el código:
Agrupar una lista de radio buttons
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class QRadioButtonGroupBox(QGroupBox):
selectItemChanged = pyqtSignal(int)
def __buttonGroupClickedSlot(self, index):
self.selectItemChanged.emit(index)
def __init__(self, *args):
QGroupBox.__init__(self, *args)
self.box = QFormLayout(parent=self)
self.buttonGroup = QButtonGroup()
QObject.connect(self.buttonGroup, SIGNAL("buttonClicked(int)"),
self.__buttonGroupClickedSlot)
def selectedItem(self):
return self.buttonGroup.checkedId()
def setChecked_(self, index, isChecked=True):
self.buttonGroup.button(index).setChecked(isChecked)
def addItem(self, text, isChecked=False):
radioButton = QRadioButton(text)
index = len(self.buttonGroup.buttons())
self.buttonGroup.addButton(radioButton, index)
self.buttonGroup.button(index).setChecked(isChecked)
self.box.addRow(radioButton)
return index
def addItems(self, *items):
for item in items:
self.addItem(item)
def removeItems(self):
for button in self.buttonGroup.buttons():
self.buttonGroup.removeButton(button)
self.box.removeWidget(button)
selectedItem
retorna el número de radiobutton seleccionada, setChecked_
permite seleccionar uno de los radiobuttons de la lista, addItem
y addItems
sirve para añadir radiobuttons y removeItems
para eliminar la lista completa de radiobutton. También incluye el signal selectItemChanged
que se dispara cuando el usuario selecciona un radiosbutton de la lista.
A continuación una demo:
def selectedItemChangedSlot(index):
print 'ha seleccionado:', index
app = QApplication(sys.argv)
main = QRadioButtonGroupBox('Mi color favorito')
main.selectItemChanged.connect(selectedItemChangedSlot)
main.addItem('1')
main.addItem('2')
main.addItem('3')
main.removeItems()
main.addItem('Rojo')
main.addItem('Azul', isChecked=True)
main.addItem('Amarillo')
main.addItems('Marron', 'Naranja', 'Verde')
main.show()
sys.exit(app.exec_())
Resultado:

Punto Extra
A veces puede ser interesante tener la posibilidad de acompañar al radio button de un widget extra. El siguiente código permite esto:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import sys
class QRadioButtonGroupBox(QGroupBox):
selectItemChanged = pyqtSignal(int, QWidget)
def __setEnabledWidget(self, index):
widget = None
for button in self.buttonGroup.buttons():
if button.buddie:
if index == self.buttonGroup.id(button):
button.buddie.setEnabled(True)
widget = button.buddie
else:
button.buddie.setEnabled(False)
return widget
def __buttonGroupClickedSlot(self, index):
widget = self.__setEnabledWidget(index)
self.selectItemChanged.emit(index, widget)
def __init__(self, *args):
QGroupBox.__init__(self, *args)
self.box = QFormLayout(parent=self)
self.buttonGroup = QButtonGroup()
QObject.connect(self.buttonGroup, SIGNAL("buttonClicked(int)"),
self.__buttonGroupClickedSlot)
def selectedItem(self):
return self.buttonGroup.checkedId()
def buddie(self, index):
button = self.buttonGroup.button(index)
return button.buddie
def setChecked_(self, index):
self.__setEnabledWidget(index)
self.buttonGroup.button(index).setChecked(True)
def addItem(self, text, widget=None, isChecked=False):
radioButton = QRadioButton(text)
index = len(self.buttonGroup.buttons())
self.buttonGroup.addButton(radioButton, index)
self.buttonGroup.button(index).setChecked(isChecked)
radioButton.buddie = widget
if widget:
self.box.addRow(radioButton, widget)
widget.setEnabled(isChecked)
else:
self.box.addRow(radioButton)
return index
def addItems(self, *items):
for item in items:
self.addItem(item)
def removeItems(self):
for button in self.buttonGroup.buttons():
self.buttonGroup.removeButton(button)
if button.buddie:
self.box.removeWidget(button.buddie)
button.buddie = None
self.box.removeWidget(button)
Una demo:
def selectedItemChangedSlot(index, widget):
print 'ha seleccionado:', index
print 'widget asociado:', widget
app = QApplication(sys.argv)
main = QRadioButtonGroupBox('Mi color favorito')
main.selectItemChanged.connect(selectedItemChangedSlot)
main.addItem('Rojo')
main.addItem('Azul', isChecked=True)
main.addItem('Amarillo')
main.addItems('Marron', 'Naranja', 'Verde')
colores = QComboBox()
colores.addItems(['violeta', 'fucsia', 'lima'])
main.addItem('otro color', widget=colores)
main.addItem('mas colores:', QLineEdit())
main.show()
sys.exit(app.exec_())
Resultado:
