从 QSettings 恢复时正确加载小部件 [英] Loading Widgets properly while restoring from QSettings

查看:65
本文介绍了从 QSettings 恢复时正确加载小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用以下代码来保存我输入的文本.例如,如果我在 gui 中用blablbalbla"填充一行,关闭程序,重新打开它,该文本将在那里.但是,使用此代码会破坏我的 GUI.我假设这是因为它是从 QSettings 加载的,但不知何故我的 QtWidgets 没有加载进来.如何在保持代码激活的同时加载我的 QT Widgets?:/

I'm using the below code to save my entered text. For example, if I fill a line in my gui with "blablbalbla", close the program, open it back up, that text will be there. However, using this code guts my GUI. I'm assuming it is because it's loading from QSettings and somehow my QtWidgets aren't loading in. How can I have my QT Widgets load in while keeping the code activated? :/

def restore(settings):
    finfo = QFileInfo(settings.fileName())

    if finfo.exists() and finfo.isFile():
        for w in qApp.allWidgets():
            mo = w.metaObject()
            if w.objectName() != "":
                for i in range(mo.propertyCount()):
                    name = mo.property(i).name()
                    val = settings.value("{}/{}".format(w.objectName(), name), w.property(name))
                    w.setProperty(name, val)

def save(settings):
    for w in qApp.allWidgets():
        mo = w.metaObject()
        if w.objectName() != "":
            for i in range(mo.propertyCount()):
                name = mo.property(i).name()
                settings.setValue("{}/{}".format(w.objectName(), name), w.property(name))

class Window(QtWidgets.QMainWindow, Ui_MainWindow):
    settings = QSettings("gui.ini", QSettings.IniFormat)
    def __init__(self, cList):
        super().__init__()

        self.setupUi(self)
        restore(self.settings)


    def closeEvent(self, event):
        save(self.settings)
        QMainWindow.closeEvent(self, event)

有趣的是,如果我删除我的 .ini 文件,它第一次运行正常.我收到此错误:

edit: interestingly, if i delete my .ini file, it works fine the first time. I'm getting this error:

C:file.py:847: DeprecationWarning: an integer is required (got type InputMethodHints).  Implicit conversion to integers using __int__ is deprecated, and may be removed in a future version of Python.
  val = settings.value("{}/{}".format(w.objectName(), name), w.property(name))
C:file.py:847: DeprecationWarning: an integer is required (got type Alignment).  Implicit conversion to integers using __int__ is deprecated, and may be removed in a future version of Python.
  val = settings.value("{}/{}".format(w.objectName(), name), w.property(name))

编辑 2:

Python 3.8.1

Python 3.8.1

这是我的 UI 主窗口.我这里没有添加任何代码:

Here's my UI MainWindow. I haven't added any code here:

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.setEnabled(True)
        MainWindow.resize(444, 676)
        MainWindow.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly)
        MainWindow.setAnimated(True)
        MainWindow.setTabShape(QtWidgets.QTabWidget.Rounded)
        self.centralwidget = QtWidgets.QWidget(MainWindow)

<小时>

完整的图形用户界面代码:


Full GUI code:

from __future__ import print_function


from PyQt5 import QtCore, QtGui, QtWidgets

from PyQt5.QtCore import QFileInfo, QSettings, Qt
from PyQt5.QtGui import QIcon, QColor, QPalette
from PyQt5.QtWidgets import (
    qApp,
    QApplication,
    QMainWindow,
    QFormLayout,
    QLineEdit,
    QTabWidget,
    QWidget,
    QAction,
)


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(506, 455)
        MainWindow.setEnabled(True)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.layoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.layoutWidget.setGeometry(QtCore.QRect(10, 10, 480, 401))
        self.layoutWidget.setObjectName("layoutWidget")
        self.formLayout = QtWidgets.QFormLayout(self.layoutWidget)
        self.formLayout.setContentsMargins(0, 0, 0, 0)
        self.formLayout.setObjectName("formLayout")
        self.label_2 = QtWidgets.QLabel(self.layoutWidget)
        self.label_2.setObjectName("label_2")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label_2)
        self.dateEdit = QtWidgets.QDateEdit(self.layoutWidget)
        self.dateEdit.setObjectName("dateEdit")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.dateEdit)
        self.label = QtWidgets.QLabel(self.layoutWidget)
        self.label.setObjectName("label")
        self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label)
        self.comboBox = QtWidgets.QComboBox(self.layoutWidget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
        )
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.comboBox.sizePolicy().hasHeightForWidth())
        self.comboBox.setSizePolicy(sizePolicy)
        self.comboBox.setMinimumSize(QtCore.QSize(312, 27))
        self.comboBox.setMaximumSize(QtCore.QSize(312, 27))
        self.comboBox.setObjectName("comboBox")
        self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.comboBox)
        self.label_3 = QtWidgets.QLabel(self.layoutWidget)
        self.label_3.setObjectName("label_3")
        self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_3)
        self.comboBox_2 = QtWidgets.QComboBox(self.layoutWidget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
        )
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.comboBox_2.sizePolicy().hasHeightForWidth())
        self.comboBox_2.setSizePolicy(sizePolicy)
        self.comboBox_2.setMinimumSize(QtCore.QSize(312, 27))
        self.comboBox_2.setMaximumSize(QtCore.QSize(312, 27))
        self.comboBox_2.setObjectName("comboBox_2")
        self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.comboBox_2)
        self.label_4 = QtWidgets.QLabel(self.layoutWidget)
        self.label_4.setObjectName("label_4")
        self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_4)
        self.comboBox_3 = QtWidgets.QComboBox(self.layoutWidget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
        )
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.comboBox_3.sizePolicy().hasHeightForWidth())
        self.comboBox_3.setSizePolicy(sizePolicy)
        self.comboBox_3.setMinimumSize(QtCore.QSize(312, 27))
        self.comboBox_3.setMaximumSize(QtCore.QSize(312, 27))
        self.comboBox_3.setObjectName("comboBox_3")
        self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.comboBox_3)
        self.label_5 = QtWidgets.QLabel(self.layoutWidget)
        self.label_5.setObjectName("label_5")
        self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_5)
        self.comboBox_4 = QtWidgets.QComboBox(self.layoutWidget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
        )
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.comboBox_4.sizePolicy().hasHeightForWidth())
        self.comboBox_4.setSizePolicy(sizePolicy)
        self.comboBox_4.setMinimumSize(QtCore.QSize(312, 27))
        self.comboBox_4.setMaximumSize(QtCore.QSize(312, 27))
        self.comboBox_4.setObjectName("comboBox_4")
        self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.comboBox_4)
        self.label_6 = QtWidgets.QLabel(self.layoutWidget)
        self.label_6.setObjectName("label_6")
        self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_6)
        self.comboBox_5 = QtWidgets.QComboBox(self.layoutWidget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
        )
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.comboBox_5.sizePolicy().hasHeightForWidth())
        self.comboBox_5.setSizePolicy(sizePolicy)
        self.comboBox_5.setMinimumSize(QtCore.QSize(312, 27))
        self.comboBox_5.setMaximumSize(QtCore.QSize(312, 27))
        self.comboBox_5.setObjectName("comboBox_5")
        self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.comboBox_5)
        self.label_11 = QtWidgets.QLabel(self.layoutWidget)
        self.label_11.setObjectName("label_11")
        self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_11)
        self.plainTextEdit = QtWidgets.QPlainTextEdit(self.layoutWidget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
        )
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.plainTextEdit.sizePolicy().hasHeightForWidth()
        )
        self.plainTextEdit.setSizePolicy(sizePolicy)
        self.plainTextEdit.setMinimumSize(QtCore.QSize(312, 30))
        self.plainTextEdit.setMaximumSize(QtCore.QSize(312, 30))
        self.plainTextEdit.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.plainTextEdit.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.plainTextEdit.setSizeAdjustPolicy(
            QtWidgets.QAbstractScrollArea.AdjustIgnored
        )
        self.plainTextEdit.setObjectName("plainTextEdit")
        self.formLayout.setWidget(
            6, QtWidgets.QFormLayout.FieldRole, self.plainTextEdit
        )
        self.label_8 = QtWidgets.QLabel(self.layoutWidget)
        self.label_8.setObjectName("label_8")
        self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_8)
        self.plainTextEdit_2 = QtWidgets.QPlainTextEdit(self.layoutWidget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
        )
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.plainTextEdit_2.sizePolicy().hasHeightForWidth()
        )
        self.plainTextEdit_2.setSizePolicy(sizePolicy)
        self.plainTextEdit_2.setMinimumSize(QtCore.QSize(312, 30))
        self.plainTextEdit_2.setMaximumSize(QtCore.QSize(312, 30))
        self.plainTextEdit_2.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.plainTextEdit_2.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.plainTextEdit_2.setSizeAdjustPolicy(
            QtWidgets.QAbstractScrollArea.AdjustIgnored
        )
        self.plainTextEdit_2.setObjectName("plainTextEdit_2")
        self.formLayout.setWidget(
            7, QtWidgets.QFormLayout.FieldRole, self.plainTextEdit_2
        )
        self.label_9 = QtWidgets.QLabel(self.layoutWidget)
        self.label_9.setObjectName("label_9")
        self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_9)
        self.plainTextEdit_3 = QtWidgets.QPlainTextEdit(self.layoutWidget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
        )
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.plainTextEdit_3.sizePolicy().hasHeightForWidth()
        )
        self.plainTextEdit_3.setSizePolicy(sizePolicy)
        self.plainTextEdit_3.setMinimumSize(QtCore.QSize(312, 30))
        self.plainTextEdit_3.setMaximumSize(QtCore.QSize(312, 30))
        self.plainTextEdit_3.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.plainTextEdit_3.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.plainTextEdit_3.setSizeAdjustPolicy(
            QtWidgets.QAbstractScrollArea.AdjustIgnored
        )
        self.plainTextEdit_3.setObjectName("plainTextEdit_3")
        self.formLayout.setWidget(
            8, QtWidgets.QFormLayout.FieldRole, self.plainTextEdit_3
        )
        self.label_10 = QtWidgets.QLabel(self.layoutWidget)
        self.label_10.setObjectName("label_10")
        self.formLayout.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.label_10)
        self.plainTextEdit_4 = QtWidgets.QPlainTextEdit(self.layoutWidget)
        sizePolicy = QtWidgets.QSizePolicy(
            QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed
        )
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.plainTextEdit_4.sizePolicy().hasHeightForWidth()
        )
        self.plainTextEdit_4.setSizePolicy(sizePolicy)
        self.plainTextEdit_4.setMinimumSize(QtCore.QSize(312, 30))
        self.plainTextEdit_4.setMaximumSize(QtCore.QSize(312, 30))
        self.plainTextEdit_4.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.plainTextEdit_4.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
        self.plainTextEdit_4.setSizeAdjustPolicy(
            QtWidgets.QAbstractScrollArea.AdjustIgnored
        )
        self.plainTextEdit_4.setObjectName("plainTextEdit_4")
        self.formLayout.setWidget(
            9, QtWidgets.QFormLayout.FieldRole, self.plainTextEdit_4
        )
        self.pushButton = QtWidgets.QPushButton(self.layoutWidget)
        self.pushButton.setMinimumSize(QtCore.QSize(101, 24))
        self.pushButton.setMaximumSize(QtCore.QSize(101, 24))
        self.pushButton.setObjectName("pushButton")
        self.formLayout.setWidget(10, QtWidgets.QFormLayout.FieldRole, self.pushButton)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 506, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label_2.setText(_translate("MainWindow", "test"))
        self.label.setText(_translate("MainWindow", "test"))
        self.label_3.setText(_translate("MainWindow", "test"))
        self.label_4.setText(_translate("MainWindow", "test"))
        self.label_5.setText(_translate("MainWindow", "test"))
        self.label_6.setText(_translate("MainWindow", "test"))
        self.label_11.setText(_translate("MainWindow", "test"))
        self.label_8.setText(_translate("MainWindow", "test"))
        self.label_9.setText(_translate("MainWindow", "test"))
        self.label_10.setText(_translate("MainWindow", "test"))
        self.pushButton.setText(_translate("MainWindow", "Go"))


def restore(settings):
    finfo = QFileInfo(settings.fileName())

    if finfo.exists() and finfo.isFile():
        for w in qApp.allWidgets():
            mo = w.metaObject()
            if w.objectName() != "":
                for i in range(mo.propertyCount()):
                    name = mo.property(i).name()
                    val = settings.value(
                        "{}/{}".format(w.objectName(), name), w.property(name)
                    )
                    w.setProperty(name, val)


def save(settings):
    for w in qApp.allWidgets():
        mo = w.metaObject()
        if w.objectName() != "":
            for i in range(mo.propertyCount()):
                name = mo.property(i).name()
                settings.setValue(
                    "{}/{}".format(w.objectName(), name), w.property(name)
                )


class Window(QtWidgets.QMainWindow, Ui_MainWindow):
    settings = QSettings("gui.ini", QSettings.IniFormat)

    def __init__(self):
        super().__init__()

        self.setupUi(self)
        restore(self.settings)

    def closeEvent(self, event):
        save(self.settings)
        QMainWindow.closeEvent(self, event)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Window()
    w.show()
    app.setStyle("Fusion")
    palette = QtGui.QPalette()
    palette.setColor(QtGui.QPalette.Window, QColor(27, 35, 38))
    palette.setColor(QtGui.QPalette.WindowText, QColor(234, 234, 234))
    palette.setColor(QtGui.QPalette.Base, QColor(42, 50, 53))
    palette.setColor(QtGui.QPalette.AlternateBase, QColor(12, 15, 16))
    palette.setColor(QtGui.QPalette.ToolTipBase, QColor(27, 35, 38))
    palette.setColor(QtGui.QPalette.ToolTipText, Qt.white)
    palette.setColor(QtGui.QPalette.Text, QColor(234, 234, 234))
    palette.setColor(QtGui.QPalette.Button, QColor(27, 35, 38))
    palette.setColor(QtGui.QPalette.ButtonText, Qt.white)
    palette.setColor(QtGui.QPalette.BrightText, QColor(100, 215, 222))
    palette.setColor(QtGui.QPalette.Link, QColor(126, 71, 130))
    palette.setColor(QtGui.QPalette.HighlightedText, Qt.white)
    palette.setColor(QtGui.QPalette.Disabled, QPalette.Light, Qt.black)
    palette.setColor(QtGui.QPalette.Disabled, QPalette.Shadow, QColor(12, 15, 16))
    w.setPalette(palette)
    sys.exit(app.exec_())

推荐答案

注意:警告是由于 PySide2 的不必要引入引起的,因此消除该导入将解决它(我已将其从 OP 帖子中删除版以消除不必要的导入).

文字为什么消失的问题是因为在save"函数代码中保存了所有的属性,也保存了QLabel有的空QPixmap,所以在使用restore"函数恢复信息的时候首先建立文本,然后建立 QPixmap 所以第二个将取代第一个,所以这是功能的限制.考虑到上述情况,解决方案是添加更多过滤器,如下所示:

The problem of why the text disappears is because in the "save" function code all the properties are saved, also save the null QPixmap that the QLabel has, so at the time of restoring the information using the "restore" function it is first established the text and then the QPixmap so the second will replace the first, so that's a limitation of the functions. Considering the above, the solution is to add more filters as I show below:

def value_is_valid(val):
    if isinstance(val, QtGui.QPixmap):
        return not val.isNull()
    return True


def restore(settings):
    finfo = QtCore.QFileInfo(settings.fileName())

    if finfo.exists() and finfo.isFile():
        for w in QtWidgets.qApp.allWidgets():
            if w.objectName():
                mo = w.metaObject()
                for i in range(mo.propertyCount()):
                    prop = mo.property(i)
                    name = prop.name()
                    last_value = w.property(name)
                    key = "{}/{}".format(w.objectName(), name)
                    if not settings.contains(key):
                        continue
                    val = settings.value(key, type=type(last_value),)
                    if (
                        val != last_value
                        and value_is_valid(val)
                        and prop.isValid()
                        and prop.isWritable()
                    ):
                        w.setProperty(name, val)


def save(settings):
    for w in QtWidgets.qApp.allWidgets():
        if w.objectName():
            mo = w.metaObject()
            for i in range(mo.propertyCount()):
                prop = mo.property(i)
                name = prop.name()
                key = "{}/{}".format(w.objectName(), name)
                val = w.property(name)
                if value_is_valid(val) and prop.isValid() and prop.isWritable():
                    settings.setValue(key, w.property(name))

这篇关于从 QSettings 恢复时正确加载小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆