Home > PyQt5, python > PyQt5: QRadioButton

PyQt5: QRadioButton

20 Marzo 2019

Torna all’indice degli appunti

QRadioButton

Per creare i radiobutton si utilizza il costruttore QRadioButton(label).
Quando si hanno più opzioni con i radio button, la scelta di una opzione, escluderà automaticamente le altre.
L’esempio sequente mostra come creare i radio button.

from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QWidget, QApplication, QBoxLayout, QRadioButton
import sys


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle("QRadioButton Example")
        self.central_widget = FormWidget(self)
        self.setCentralWidget(self.central_widget)
        self.resize(300, 100)


class FormWidget(QWidget):
    def __init__(self, parent):
        super(FormWidget, self).__init__(parent)
        layout = QBoxLayout(QBoxLayout.TopToBottom)
        self.radio_button1 = QRadioButton("Italy", self)
        self.radio_button2 = QRadioButton("France", self)
        self.radio_button3 = QRadioButton("Spain", self)
        layout.addWidget(self.radio_button1, 0)
        layout.addWidget(self.radio_button2, 0)
        layout.addWidget(self.radio_button3, 0)
        self.setLayout(layout)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

E’ possibile settare di default a checked (selezionato) un radiobutton, con il metodo setChecked,
passando come argomento True:

...
        self.radio_button1 = QRadioButton("Italy", self)
        self.radio_button2 = QRadioButton("France", self)
        self.radio_button3 = QRadioButton("Spain", self)
        self.radio_button2.setChecked(True)
...

Se vogliamo fare in modo che una delle opzioni, non sia selezionabile, possiamo utilizzare il metodo setCheckable
passando come argomento False:

...
        self.radio_button1 = QRadioButton("Italy", self)
        self.radio_button2 = QRadioButton("France", self)
        self.radio_button3 = QRadioButton("Spain", self)
        self.radio_button2.setChecked(True)
        self.radio_button3.setCheckable(False)
...

Icons

Per inserire una icona a fianco del radio button, si utilizza lo stesso procedimento utilizzato per il QPushButton.
Si crea quindi un’oggetto QIcon e lo si associa al radio button:

...
from PyQt5.QtGui import QIcon
...
        self.radio_button1 = QRadioButton("Italy", self)
        self.radio_button1.setIcon(QIcon("Italy.png"))
        self.radio_button2 = QRadioButton("France", self)
        self.radio_button2.setIcon(QIcon("France.png"))
        self.radio_button3 = QRadioButton("Spain", self)
        self.radio_button3.setIcon(QIcon("Spain.png"))
...

Colore

valgono le regole già viste per gli altri widget, ovvero si utilizzano QPalette e QColor sugli
elementi backgroundRole e foregroundRole del widget interessato:

...
from PyQt5.QtGui import QColor

...
        # background
        bg_color = QColor('Yellow')
        palette = self.radio_button1.palette()
        rb1_background = self.radio_button1.backgroundRole()
        palette.setColor(rb1_background, bg_color)
        fg_color = QColor('Red')
        # foreground
        rb1_foreground = self.radio_button1.foregroundRole()
        palette.setColor(rb1_foreground, fg_color)
        self.radio_button1.setPalette(palette)
        self.radio_button1.setAutoFillBackground(True)
...

Font

Anche la modifica del font non cambia, si utilizza cioè il costruttore QFont nella solita maniera:

...
        # Font
        font = QFont("Lucida", 14, QFont.Bold)
        self.radio_button1.setFont(font)
...

Segnali

Quando si clicca su un radio button viene emesso il segnale toggled.
Una volta connesso tale segnale al proprio slot, possiamo controllare quale radio button sia stato selezionato utilizzando
il metodo isChecked.

O creiamo uno slot per ogni radio button:

...
        self.radio_button1.toggled.connect(self.on_radio_button_1)
        self.radio_button2.toggled.connect(self.on_radio_button_2)
        self.radio_button3.toggled.connect(self.on_radio_button_3)

    def on_radio_button_1(self):
        if self.radio_button1.isChecked():
            print("click on %s" % self.radio_button1.text())

    def on_radio_button_2(self):
        if self.radio_button2.isChecked():
            print("click on %s" % self.radio_button2.text())

    def on_radio_button_3(self):
        if self.radio_button3.isChecked():
            print("click on %s" % self.radio_button3.text())
...

O ne creiamo uno condiviso, al quale passare come argomento il widget:

...
        self.radio_button1.toggled.connect(
            lambda: self.on_radio_button(self.radio_button1))
        self.radio_button2.toggled.connect(
            lambda: self.on_radio_button(self.radio_button2))
        self.radio_button3.toggled.connect(
            lambda: self.on_radio_button(self.radio_button3))

    @staticmethod
    def on_radio_button(widget):
        if widget.isChecked():
            print("click on %s" % widget.text())
...

Testo

Il testo può essere settato con il metodo setText anche dopo aver istanziato l’oggetto.
E’ possibile anche utilizzare gli ampersand con il medesimo metodo.
Stesso discorso vale per settare un tooltip tramite metodo setToolTip:

...
        self.radio_button1 = QRadioButton()
        self.radio_button1.setText("&Italy")  # Ampersand
        self.radio_button1.setIcon(QIcon("Italy.png"))
        self.radio_button1.setToolTip("Select Italy")  # Tooltip
...

Per evitare effetti indesiderati tra radiobuttons, è possibile utilizzare i ButtonGroup, oggetti invisibili che
hanno il solo scopo di raggruppare bottoni isolandoli da altri con i quali non devono interagire.

BUTTONGROUP

Il costruttore è il QButtonGroup.
Per aggiungere un bottone al gruppo, si utilizza il metodo addButton(widget, id).
Widget è il bottone che vogliamo aggiungere a quel gruppo, id è l’indice che verrà assegnato al bottone e che utilizzeremo per riconoscerlo nel gruppo.

>> from PyQt5.QtWidgets import QApplication, QRadioButton, QButtonGroup
>>> app = QApplication([])
>>> radio_button1 = QRadioButton("Italy")
>>> radio_button2 = QRadioButton("France")
>>> radio_button3 = QRadioButton("Spain")
>>> buttongroup = QButtonGroup()
>>> buttongroup.addButton(radio_button1, 1)
>>> buttongroup.addButton(radio_button2, 2)
>>> buttongroup.addButton(radio_button3, 3)

Per conoscere quali bottoni fanno parte di un gruppo, si utilizza il metodo buttons:

>>> for button in buttongroup.buttons():
...     print(button.text(), button)
...     
Italy <PyQt5.QtWidgets.QRadioButton object at 0x0343E120>
France <PyQt5.QtWidgets.QRadioButton object at 0x0343E0D0>
Spain <PyQt5.QtWidgets.QRadioButton object at 0x0343E1C0>

Per rimuovere un bottone da un gruppo si utilizza il metodo removeButton:

>>> buttongroup.removeButton(radio_button3)
>>> for button in buttongroup.buttons():
...     print(button.text(), button)
...     
Italy <PyQt5.QtWidgets.QRadioButton object at 0x0343E120>
France <PyQt5.QtWidgets.QRadioButton object at 0x0343E0D0>

Gli id precedenti, ci consentono di recuperare un bottone tramite il metodo button(id):

>>> button = buttongroup.button(1)
>>> button
<PyQt5.QtWidgets.QRadioButton object at 0x0343E120>
>>> button.text()
'Italy'

Se invece abbiamo necessità di recuperare l’id di un bottone utilizziamo il metodo id(button):

>>> buttongroup.id(radio_button2)
2

Per cambiare l’id del bottone all’interno del gruppo, si utilizza il metodo setId(button, newid):

>>> buttongroup.setId(radio_button2, 200)
>>> buttongroup.id(radio_button2)
200
>>> button = buttongroup.button(200)
>>> button.text()
'France'

Se vogliamo recuperare il bottone settato a checked, utilizziamo il metodo checkedButton:

>>> buttongroup.checkedButton()  # Nessun bottone settato a checked
>>> radio_button1.setChecked(True)
>>> buttongroup.checkedButton()
<PyQt5.QtWidgets.QRadioButton object at 0x0343E120>

Signal

Quando un bottone appartenente ad un button-group viene cliccato, viene emesso un segnale buttonClicked.
Tale segnale emette anche l’id del bottone cliccato. E’ quindi possibile connettere tale segnale ad uno slot:

from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QWidget, QApplication, QBoxLayout
from PyQt5.QtWidgets import QRadioButton, QButtonGroup
from PyQt5.QtGui import QIcon
import sys


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle("QRadioButton Example")
        self.central_widget = FormWidget(self) 
        self.setCentralWidget(self.central_widget)
        self.resize(300, 100)


class FormWidget(QWidget):
    def __init__(self, parent):
        super(FormWidget, self).__init__(parent)
        layout = QBoxLayout(QBoxLayout.TopToBottom)
        self.button_group = QButtonGroup()

        self.radio_button1 = QRadioButton()
        self.radio_button1.setText("Italy")
        self.radio_button1.setIcon(QIcon("Italy.png"))
        self.radio_button1.setToolTip("Select Italy")
        self.button_group.addButton(self.radio_button1, 1)

        self.radio_button2 = QRadioButton("France", self)
        self.radio_button2.setIcon(QIcon("France.png"))
        self.button_group.addButton(self.radio_button2, 2)

        self.radio_button3 = QRadioButton("Spain", self)
        self.radio_button3.setIcon(QIcon("Spain.png"))
        self.button_group.addButton(self.radio_button3, 3)

        layout.addWidget(self.radio_button1, 0)
        layout.addWidget(self.radio_button2, 0)
        layout.addWidget(self.radio_button3, 0)
        self.setLayout(layout)

        self.button_group.buttonClicked[int].connect(self.on_radio_button)

    def on_radio_button(self, id):
        for button in self.button_group.buttons():
            if button is self.button_group.button(id):
                print("click on %s" % button.text())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

Volendo forzare la scelta multipla sui radiobutton appartenenti allo stesso gruppo, si può utilizzare il metodo
setExclusive:

...
        self.button_group = QButtonGroup()
        self.button_group.setExclusive(False)
...

Nota:

Se escludessimo da gruppo uno dei tre radio button e il setExclusive sul gruppo fosse settato a True, questa caratteristica coinvolgerebbe solo i radio button apparrtenenti al gruppo stesso!
Ovvero sarà possibile cliccare anche il radio button escluso, che dovrà però essere collegato al proprio segnale:

from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QWidget, QApplication, QBoxLayout
from PyQt5.QtWidgets import QRadioButton, QButtonGroup
from PyQt5.QtGui import QIcon
import sys


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.setWindowTitle("QRadioButton Example")
        self.central_widget = FormWidget(self) 
        self.setCentralWidget(self.central_widget)
        self.resize(300, 100)


class FormWidget(QWidget):
    def __init__(self, parent):
        super(FormWidget, self).__init__(parent)
        layout = QBoxLayout(QBoxLayout.TopToBottom)
        self.button_group = QButtonGroup()
        self.button_group.setExclusive(True)

        radio_button1 = QRadioButton()
        radio_button1.setText("Italy")
        radio_button1.setIcon(QIcon("Italy.png"))
        radio_button1.setToolTip("Select Italy")
        self.button_group.addButton(radio_button1, 1)

        radio_button2 = QRadioButton("France", self)
        radio_button2.setIcon(QIcon("France.png"))
        self.button_group.addButton(radio_button2, 2)

        radio_button3 = QRadioButton("Spain", self)
        radio_button3.setIcon(QIcon("Spain.png"))
        # self.button_group.addButton(radio_button3, 3)  # Escluso dal gruppo

        layout.addWidget(radio_button1, 0)
        layout.addWidget(radio_button2, 0)
        layout.addWidget(radio_button3, 0)
        self.setLayout(layout)

        self.button_group.buttonClicked[int].connect(self.on_button_group)
        radio_button3.clicked.connect(
            lambda: self.on_radio_button_3(radio_button3))

    def on_button_group(self, id):
        for radio_button in self.button_group.buttons():
            if radio_button is self.button_group.button(id):
                print("[GROUP] click on %s" % radio_button.text())

    def on_radio_button_3(self, radio_button):
        print("[SINGLE] click on %s" % radio_button.text())


if __name__ == '__main__':
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())
[GROUP] click on Italy
[GROUP] click on France
[SINGLE] click on Spain

Torna all’indice degli appunti

Categorie:PyQt5, python Tag: ,
I commenti sono chiusi.