It’s my code. How to store the lastly clicked/checked button as default in the next opening of the programme? For example: If we run the programme and click the 3rd button and close the entire programme. Whenever I reopen/re-run the programme, the lastly clicked button is checked by default ( ie. third button is checked by default)
import sys from PyQt5 import QtWidgets class RadioButton(QtWidgets.QWidget): def __init__(self): super(). __init__() self.setWindowTitle("Radio Button") self.rbtn1 = QtWidgets.QRadioButton("Button1") self.rbtn1.clicked.connect(self.getvalue) self.rbtn2 = QtWidgets.QRadioButton("Button2") self.rbtn2.clicked.connect(self.getvalue) self.rbtn3 = QtWidgets.QRadioButton("Button3") self.rbtn3.clicked.connect(self.getvalue) self.rbtn4 = QtWidgets.QRadioButton("Button4") self.rbtn4.clicked.connect(self.getvalue) vbox = QtWidgets.QVBoxLayout() vbox.addWidget(self.rbtn1) vbox.addWidget(self.rbtn2) vbox.addWidget(self.rbtn3) vbox.addWidget(self.rbtn4) self.setLayout(vbox) def getvalue(self): if self.rbtn1.isChecked(): self.rbtn1.setChecked(True) print("Radio button 1 is checked") elif self.rbtn2.isChecked(): self.rbtn2.setChecked(True) print("Radio button 2 is checked") elif self.rbtn3.isChecked(): self.rbtn3.setChecked(True) print("Radio button 3 is checked") elif self.rbtn4.isChecked(): self.rbtn4.setChecked(True) print("Radio button 4 is checked") if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) win = RadioButton() win.show() sys.exit(app.exec_())
Advertisement
Answer
You can use QSettings to save and restore data. Note that values are serialized as QVariants, so you cannot, for instance, save a custom python subclass instance.
In order to properly use QSettings you must set both the Qt application name and organization name (otherwise data won’t be stored anywhere).
It is possible to save settings in other ways, but for general usage it’s better to use the default behavior.
Note that, since values are stored as strings, Qt can only try to guess the actual type, so it’s always better to specify the type when using value()
(see the case below).
Then, while by default Qt is able to automatically group radio buttons and make them exclusive (see the autoExclusive property of QAbstractButton, which is set to True for QRadioButtons), for this kind of situations it’s better to rely on a QButtonGroup, which not only allows better control on the buttons, but also allows identifying buttons member of the group by using unique IDs they were assigned to.
Finally, it’s just a matter of connecting the appropriate signal of the button group to the function that saves the currently checked button.
from PyQt5 import QtWidgets, QtCore class RadioButton(QtWidgets.QWidget): def __init__(self): super(). __init__() self.setWindowTitle("Radio Button") self.rbtn1 = QtWidgets.QRadioButton("Button1") self.rbtn2 = QtWidgets.QRadioButton("Button2") self.rbtn3 = QtWidgets.QRadioButton("Button3") self.rbtn4 = QtWidgets.QRadioButton("Button4") buttons = self.rbtn1, self.rbtn2, self.rbtn3, self.rbtn4 vbox = QtWidgets.QVBoxLayout(self) self.optionGroup = QtWidgets.QButtonGroup() for i, button in enumerate(buttons): vbox.addWidget(button) self.optionGroup.addButton(button, i) # for Qt>=5.15: # self.optionGroup.idToggled.connect(self.getvalue) # otherwise: self.optionGroup.buttonToggled[int, bool].connect(self.getvalue) self.settings = QtCore.QSettings() # read the value if it exists, otherwise use a default; note that # the type MUST be specified, otherwise numbers would be read as # strings, raising an exception and crashing the program in this case default = self.settings.value('MyOption', 2, type=int) self.optionGroup.button(default).setChecked(True) def getvalue(self, id, checked): if checked: button = self.optionGroup.button(id) print("{} is checked".format(button.text())) self.settings.setValue('MyOption', id) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) app.setOrganizationName('MyOrganization') app.setApplicationName('MyApplication') win = RadioButton() win.show() sys.exit(app.exec_())
I strongly recommend you to carefully study the whole documentation about all the classes specified above.