Search code examples
pythonqtpyqtpysideqradiobutton

How to set up and react to multiple display options?


I'm working on a GUI that will eventually run one of several data analyses depending on which the user selects. In this part of the GUI, I have four radio buttons with options, and then a display button. I would like one of four imported functions to run when the user hits display.

It boils down to something like this

import myFunction

class myUi(QtGui.QWidget):
    def retranslateUi(self, myUi):
        self.option1.clicked.connect(self.option1task)
        self.option2.clicked.connect(self.option2task)
        self.display.clicked.connect(self.displaytask)

    def option1task(self):
        #do something

    def option2task(self):
        #do something

    def displaytask(self):
        #if option 1 was clicked, run myFunction.option1()
        #if option 2 was clicked, run myFunction.option2()

I'm just having trouble making it work. Is there some way to solve it just by passing variables or will I need to use the signal/slot method?


Solution

  • First of all you do not want to react immediately when a radio button is clicked, so you do not need to connect to their clicked signal.

    Instead the radio buttons (which are automatically exclusive within the same parent) can be selected by the user and at the moment the display button is clicked, you just read out which of the radio buttons is selected (can be at most one) and do something according to which one is selected.

    For four radio buttons you can do that by a if else clause on isChecked() of the buttons.

    For larger numbers of button I recommend additionally using a QButtonGroup (documentation) which allowes to assign an integer to each button within the addButton() method and then easily retrieve the integer of the selected button with checkedId(). If no button is selected the return value is -1.

    My example (using PySide which is very similar to PyQt):

    from PySide import QtGui
    
    def do_something():
        id = g.checkedId()
        if id == -1:
            print('no option selected')
        else:
            print('selected option {}, read for display'.format(id))
    
    app = QtGui.QApplication([])
    
    w = QtGui.QWidget()
    l = QtGui.QVBoxLayout(w)
    
    # three radio buttons
    b1 = QtGui.QRadioButton('Option 1')
    l.addWidget(b1)
    b2 = QtGui.QRadioButton('Option 2')
    l.addWidget(b2)
    b3 = QtGui.QRadioButton('Option 3')
    l.addWidget(b3)
    
    # a button group (mapping from buttons to integers)
    g = QtGui.QButtonGroup(w)
    g.addButton(b1, 1)
    g.addButton(b2, 2)
    g.addButton(b3, 3)
    
    # display button
    b = QtGui.QPushButton('Display')
    b.clicked.connect(do_something)
    l.addWidget(b)
    
    w.show()
    
    app.exec_()
    

    And it looks like:

    enter image description here