You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5使用QSettings保存QRadioButton状态无法正确持久化

问题原因
  1. QSettings值类型转换错误:Linux下QSettings默认使用ini格式存储配置,布尔值会被序列化为字符串"true"/"false"存储,读取时默认返回字符串类型。你直接用bool()转换的话,非空字符串都会被转为True,哪怕是"false",导致原本应该为False的状态被错误设置为True,最终两个按钮都被设为选中。
  2. 组件添加顺序错误导致互斥规则未生效:QRadioButton的同组互斥特性,只有在多个按钮被添加到同一个父容器(这里是QGroupBox)之后才会生效。你的代码里先读取配置给两个单选按钮设置选中状态,之后才将按钮添加到QGroupBox的布局中,设置状态时互斥规则还没生效,完全可以出现两个按钮同时为True的情况。
  3. 缺少默认值配置:调用QSettings.value()时如果对应key不存在,会返回None,你直接用bool()转换得到False,不符合你初始希望“Promote Pawn Using Popup Window”默认选中的逻辑。
解决方案

修复步骤

  1. 指定QSettings返回值类型:调用value()方法时通过第三个参数type=bool让Qt自动完成正确的布尔类型转换,避免字符串转布尔的错误。
  2. 调整初始化顺序:先把单选按钮添加到QGroupBox的布局中,确保互斥规则生效后,再读取配置设置按钮状态。
  3. 添加默认值:读取配置时传入默认值,避免首次运行无配置时状态错误。

修正后的核心代码示例

import sys

from PyQt5.QtCore import QSettings
from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QGroupBox, 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)

        # 先完成布局添加,让单选按钮互斥规则先生效
        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)

        # 互斥生效后再读取配置设置状态,指定返回布尔类型、添加默认值
        self.settings = QSettings('LoneProgrammer2', 'qsettingsTest1')
        self.settings.beginGroup("Promotion Dialog")
        auto_checked = self.settings.value('auto-promote radio button checked state', False, type=bool)
        popup_checked = self.settings.value('promote using popup radio button checked state', True, type=bool)
        # 按存储的状态设置即可,互斥生效不会出现同时选中
        self.oAutoPromoteRadioBtn.setChecked(auto_checked)
        self.oUsePopupRadioBtn.setChecked(popup_checked)
        self.settings.endGroup()

        print('AT APP OPENING:')
        print('self.oAutoPromoteRadioBtn.isChecked() = ', self.oAutoPromoteRadioBtn.isChecked())
        print('self.oUsePopupRadioBtn.isChecked() = ', self.oUsePopupRadioBtn.isChecked())

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

内容的提问来源于stack exchange,提问作者Sam Quintanar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 18:39:02