【问题标题】:Saving states of QRadioButtons using QSettings not persisting values correctly in PyQt5使用 QSettings 保存 QRadioButtons 的状态未在 PyQt5 中正确保存值
【发布时间】:2021-12-05 04:05:57
【问题描述】:

我对使用 QSettings 将单选按钮的状态从一个应用程序会话保存到另一个使用 PyQt5 的结果感到困惑。 (操作系统 = Ubuntu Linux 18.04)

这些是产生令人困惑的结果的步骤:

  1. 运行应用程序;查看选中的两个单选按钮;两个按钮都像鼠标被选中一样触发
  2. 取消选择顶部单选按钮
  3. 关闭应用程序;查看单选按钮选中状态的“正确”保存
  4. 运行应用程序;即使保存了仅选择一个按钮的不同状态,这两个单选按钮也会被选中
  5. 取消选择顶部单选按钮
  6. 关闭应用程序;查看单选按钮选中状态的“正确”保存
  7. 在代码中,第18行,将QSettings('LoneProgrammer2', 'qsettingsTest1')改为QSettings('ChangeThis', 'qsettingsTest1');保存代码
  8. 运行应用程序; !!单选按钮选择反映了正确保存的值!!
  9. 关闭应用程序; 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_())

【问题讨论】:

    标签: python pyqt pyqt5 qsettings


    【解决方案1】:

    在读取设置值时最好指出类型,因为可能会造成混淆(最有可能的值将返回字符串“true”和“false”,在使用 bool 时转换为 True,因为它们是真的)。另一方面,为了增加可读性,最好创建专门的方法。

    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_())
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-08-28
      • 2013-06-12
      • 1970-01-01
      • 2018-06-27
      • 2021-11-23
      • 2020-09-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多