I'm baffled by the results of using QSettings to save the state of my radio buttons from one app session to another using PyQt5. (OS = Ubuntu Linux 18.04)
These are the steps to produce baffling results:
QSettings('LoneProgrammer2', 'qsettingsTest1')
to QSettings('ChangeThis', 'qsettingsTest1')
; save the codeCan anyone please explain what's going on here? I just want the QSettings to work.
import sys
from PyQt5.QtCore import QSettings
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QDialogButtonBox, QGroupBox, QHBoxLayout, QRadioButton
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.oAutoPromoteRadioBtn = QRadioButton("Automatically Promote to Queen")
self.oAutoPromoteRadioBtn.toggled.connect(self.on_selected)
self.oUsePopupRadioBtn = QRadioButton("Promote Pawn Using Popup Window")
self.oUsePopupRadioBtn.toggled.connect(self.on_selected)
self.oUsePopupRadioBtn.setChecked(True)
self.settings = QSettings('LoneProgrammer2', 'qsettingsTest1') # companyname, appname
self.settings.beginGroup("Promotion Dialog")
self.oAutoPromoteRadioBtn.setChecked(
bool(self.settings.value('auto-promote radio button checked state')))
self.oUsePopupRadioBtn.setChecked(
bool(self.settings.value('promote using popup radio button checked state')))
self.settings.endGroup()
print('AT APP OPENING:')
print('self.oAutoPromoteRadioBtn.isChecked() = ', self.oAutoPromoteRadioBtn.isChecked())
print('self.oUsePopupRadioBtn.isChecked() = ', self.oUsePopupRadioBtn.isChecked())
oVertLayoutForRadioButtons = QVBoxLayout()
oVertLayoutForRadioButtons.addWidget(self.oAutoPromoteRadioBtn)
oVertLayoutForRadioButtons.addWidget(self.oUsePopupRadioBtn)
self.groupbox = QGroupBox("Select pawn promotion method:")
self.groupbox.setFixedWidth(300)
self.groupbox.setFixedHeight(95)
self.groupbox.setLayout(oVertLayoutForRadioButtons)
self.oVertLayout = QVBoxLayout()
self.oVertLayout.addWidget(self.groupbox)
self.setLayout(self.oVertLayout)
def on_selected(self):
radio_button = self.sender()
if radio_button.isChecked():
if radio_button.text() == 'Automatically Promote to Queen':
print('set to auto-promote to queen')
elif radio_button.text() == 'Promote Pawn Using Popup Window':
print('set to promote pawn to queen using popup window')
def closeEvent(self, event):
# save the vars from this session
self.settings.beginGroup("Promotion Dialog")
self.settings.setValue('auto-promote radio button checked state', self.oAutoPromoteRadioBtn.isChecked())
self.settings.setValue('promote using popup radio button checked state', self.oUsePopupRadioBtn.isChecked())
self.settings.endGroup()
print()
print('AT APP CLOSE:')
print('self.oAutoPromoteRadioBtn.isChecked() = ', self.oAutoPromoteRadioBtn.isChecked())
print('self.oUsePopupRadioBtn.isChecked() = ', self.oUsePopupRadioBtn.isChecked())
if __name__ == "__main__":
app = QApplication(sys.argv)
demo = MyApp()
demo.show()
sys.exit(app.exec_())
When reading settings values it is good to indicate the type as there may be confusion (most likely value will return the strings "true" and "false" that are converted to True when using bool since they are truly). On the other hand to add readability it is better to create specialized methods.
from functools import cached_property
import sys
from PyQt5.QtCore import QSettings
from PyQt5.QtWidgets import (
QApplication,
QWidget,
QVBoxLayout,
QDialogButtonBox,
QGroupBox,
QHBoxLayout,
QRadioButton,
)
class MyApp(QWidget):
def __init__(self):
super().__init__()
self.oAutoPromoteRadioBtn = QRadioButton("Automatically Promote to Queen")
self.oAutoPromoteRadioBtn.toggled.connect(self.on_selected)
self.oUsePopupRadioBtn = QRadioButton("Promote Pawn Using Popup Window")
self.oUsePopupRadioBtn.toggled.connect(self.on_selected)
self.settings = QSettings(
"LoneProgrammer2", "qsettingsTest1"
) # companyname, appname
oVertLayoutForRadioButtons = QVBoxLayout()
oVertLayoutForRadioButtons.addWidget(self.oAutoPromoteRadioBtn)
oVertLayoutForRadioButtons.addWidget(self.oUsePopupRadioBtn)
self.groupbox = QGroupBox("Select pawn promotion method:")
self.groupbox.setFixedSize(300, 95)
self.groupbox.setLayout(oVertLayoutForRadioButtons)
self.oVertLayout = QVBoxLayout(self)
self.oVertLayout.addWidget(self.groupbox)
self.read_settings()
def on_selected(self):
radio_button = self.sender()
if radio_button.isChecked():
if radio_button.text() == "Automatically Promote to Queen":
print("set to auto-promote to queen")
elif radio_button.text() == "Promote Pawn Using Popup Window":
print("set to promote pawn to queen using popup window")
@cached_property
def settings(self):
return QSettings("LoneProgrammer2", "qsettingsTest1")
@property
def mapping_settings(self):
return {
"Promotion Dialog": [
("auto-promote radio button checked state", self.oAutoPromoteRadioBtn),
(
"promote using popup radio button checked state",
self.oUsePopupRadioBtn,
),
]
}
def read_settings(self):
for group_key, values in self.mapping_settings.items():
self.settings.beginGroup(group_key)
for (key, checkbox) in values:
value = self.settings.value(key, type=bool)
checkbox.setChecked(value)
self.settings.endGroup()
def write_settings(self):
for group_key, values in self.mapping_settings.items():
self.settings.beginGroup(group_key)
for (key, checkbox) in values:
self.settings.setValue(key, checkbox.isChecked())
self.settings.endGroup()
def closeEvent(self, event):
super().closeEvent(event)
self.write_settings()
if __name__ == "__main__":
app = QApplication(sys.argv)
demo = MyApp()
demo.show()
sys.exit(app.exec_())