pythonpython-3.xpyqt5qsettingsqcheckbox

Restoring QCheckBox with Qsettings


Having QCheckBox wants to save and restore checkstate after closing file.

Tried following but it does not really work!

The code:

import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class SecondOrder(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(SecondOrder, self).__init__(parent)
        self.setFont(QtGui.QFont("Helvetica", 8, QtGui.QFont.Normal, italic=False))

        curvaturelabel = QtWidgets.QLabel('Nominal curvature')
        stiffnesslabel = QtWidgets.QLabel('Nominal stiffness')
        simcurvaturelabel = QtWidgets.QLabel('Simplified nominal curvature')   

        self.curvaturecheck = QtWidgets.QCheckBox()
        self.stiffnesscheck = QtWidgets.QCheckBox()
        self.simcurvaturecheck = QtWidgets.QCheckBox()

        self.clay = QtWidgets.QVBoxLayout()
        self.clay.addWidget(curvaturelabel)
        self.clay.addWidget(stiffnesslabel)
        self.clay.addWidget(simcurvaturelabel)

        self.dlay = QtWidgets.QVBoxLayout()
        self.dlay.addWidget(self.curvaturecheck)
        self.dlay.addWidget(self.stiffnesscheck)
        self.dlay.addWidget(self.simcurvaturecheck)

        grid = QtWidgets.QGridLayout(self)
        grid.addLayout(self.dlay, 0, 0)
        grid.addLayout(self.clay, 0, 1)

        Secondorder_Group = QtWidgets.QGroupBox(self)
        Secondorder_Group.setTitle("&Second order analysis method")
        Secondorder_Group.setLayout(grid)

        self.elay = QtWidgets.QHBoxLayout(self)
        self.elay.addWidget(Secondorder_Group)     
        self.elay.setSizeConstraint(self.elay.SetFixedSize)

        group = QtWidgets.QButtonGroup(self) 
        group.addButton(self.curvaturecheck) 
        group.addButton(self.stiffnesscheck) 
        group.addButton(self.simcurvaturecheck)

        self.readSettings()

        self.curvaturecheck.stateChanged.connect(lambda: self.writeSettings())
        self.stiffnesscheck.stateChanged.connect(lambda: self.writeSettings())
        self.simcurvaturecheck.stateChanged.connect(lambda: self.writeSettings())

    def readSettings(self):
        settings = QtCore.QSettings('file.ini')
        settings.beginGroup("QCheckBox")
        self.curvaturecheck.setCheckState(settings.value("A", QtCore.Qt.Checked, bool))
        self.stiffnesscheck.setCheckState(settings.value("B", False, bool))
        self.simcurvaturecheck.setCheckState(settings.value("C", False, bool))
        settings.endGroup()

    def writeSettings(self):
        settings = QtCore.QSettings('file.ini')
        settings.beginGroup("QCheckBox")
        settings.setValue("A", self.curvaturecheck.isCheckable())
        settings.setValue("B", self.stiffnesscheck.isCheckable())
        settings.setValue("C", self.simcurvaturecheck.isCheckable())
        settings.endGroup()


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = SecondOrder()
    w.show()
    sys.exit(app.exec_())

Note that following codes are tried, it really saves and restores but it mix multiple checks? wants to be able to check once and restore.

    settings.setValue("A", self.curvaturecheck.isChecked())
    settings.setValue("B", self.stiffnesscheck.isChecked())
    settings.setValue("C", self.simcurvaturecheck.isChecked())

Solution

  • If you are going to save a type T data then you must use the function that uses type T, in your case you save a boolean with isChecked() and you want to use the function setCheckState() that uses a Qt::CheckState type causing the error.

    Considering the above there are 2 solutions:

    def readSettings(self):
        settings = QtCore.QSettings("file.ini")
        settings.beginGroup("QCheckBox")
        self.curvaturecheck.setChecked(settings.value("A", True, bool))
        self.stiffnesscheck.setChecked(settings.value("B", False, bool))
        self.simcurvaturecheck.setChecked(settings.value("C", False, bool))
        settings.endGroup()
    
    def writeSettings(self):
        settings = QtCore.QSettings("file.ini")
        settings.beginGroup("QCheckBox")
        settings.setValue("A", self.curvaturecheck.isChecked())
        settings.setValue("B", self.stiffnesscheck.isChecked())
        settings.setValue("C", self.simcurvaturecheck.isChecked())
        settings.endGroup()
    
    def readSettings(self):
        settings = QtCore.QSettings("file.ini")
        settings.beginGroup("QCheckBox")
        self.curvaturecheck.setCheckState(
            settings.value("A", QtCore.Qt.Checked, QtCore.Qt.CheckState)
        )
        self.stiffnesscheck.setCheckState(
            settings.value("B", QtCore.Qt.Unchecked, QtCore.Qt.CheckState)
        )
        self.simcurvaturecheck.setCheckState(
            settings.value("C", QtCore.Qt.Unchecked, QtCore.Qt.CheckState)
        )
        settings.endGroup()
    
    def writeSettings(self):
        settings = QtCore.QSettings("file.ini")
        settings.beginGroup("QCheckBox")
        settings.setValue("A", self.curvaturecheck.checkState())
        settings.setValue("B", self.stiffnesscheck.checkState())
        settings.setValue("C", self.simcurvaturecheck.checkState())
        settings.endGroup()
    

    It is recommended that you delete the .ini file located in settings.fileName().

    On the other hand it is not necessary to use lambda functions, change your code to:

    self.curvaturecheck.stateChanged.connect(self.writeSettings)
    self.stiffnesscheck.stateChanged.connect(self.writeSettings)
    self.simcurvaturecheck.stateChanged.connect(self.writeSettings)