使用 QSettings 保存 QRadioButtons 的状态不能在 PyQt5 中正确保存值
Saving states of QRadioButtons using QSettings not persisting values correctly in PyQt5
我对使用 QSettings 将我的单选按钮状态从一个应用程序会话保存到另一个使用 PyQt5 的结果感到困惑。 (OS = Ubuntu Linux 18.04)
这些是产生莫名其妙结果的步骤:
- 运行 应用;看到两个单选按钮都被选中;两个按钮都会触发,就好像鼠标被选中一样
- 取消选择顶部单选按钮
- 关闭应用;查看 'correct' 单选按钮选中状态的保存
- 运行 应用;两个单选按钮都被选中,即使在只选择一个按钮的情况下保存了不同的状态
- 取消选择顶部单选按钮
- 关闭应用;查看 'correct' 单选按钮选中状态的保存
- 在代码中,第18行,将
QSettings('LoneProgrammer2', 'qsettingsTest1')
改为QSettings('ChangeThis', 'qsettingsTest1')
;保存代码
- 运行 应用; !!正确保存的值反映在单选按钮选择中!!
- 关闭应用;
10 运行 应用程序,现在有两个单选按钮再次被选中!
谁能解释一下这是怎么回事?我只想让 QSettings 正常工作。
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_())
读取设置值时最好指明类型,因为可能会造成混淆(最有可能的值是 return 使用 bool 时转换为 True 的字符串“true”和“false”,因为它们是真的)。另一方面,为了增加可读性,最好创建专门的方法。
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_())
我对使用 QSettings 将我的单选按钮状态从一个应用程序会话保存到另一个使用 PyQt5 的结果感到困惑。 (OS = Ubuntu Linux 18.04)
这些是产生莫名其妙结果的步骤:
- 运行 应用;看到两个单选按钮都被选中;两个按钮都会触发,就好像鼠标被选中一样
- 取消选择顶部单选按钮
- 关闭应用;查看 'correct' 单选按钮选中状态的保存
- 运行 应用;两个单选按钮都被选中,即使在只选择一个按钮的情况下保存了不同的状态
- 取消选择顶部单选按钮
- 关闭应用;查看 'correct' 单选按钮选中状态的保存
- 在代码中,第18行,将
QSettings('LoneProgrammer2', 'qsettingsTest1')
改为QSettings('ChangeThis', 'qsettingsTest1')
;保存代码 - 运行 应用; !!正确保存的值反映在单选按钮选择中!!
- 关闭应用; 10 运行 应用程序,现在有两个单选按钮再次被选中!
谁能解释一下这是怎么回事?我只想让 QSettings 正常工作。
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_())
读取设置值时最好指明类型,因为可能会造成混淆(最有可能的值是 return 使用 bool 时转换为 True 的字符串“true”和“false”,因为它们是真的)。另一方面,为了增加可读性,最好创建专门的方法。
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_())