Правильная загрузка виджетов при восстановлении из QSettings - PullRequest
0 голосов
/ 02 февраля 2020

Я использую приведенный ниже код для сохранения введенного текста. Например, если я заполню строку в своем gui «blablbalbla», закрою программу, снова открою ее, этот текст будет там. Тем не менее, использование этого кода заставляет меня GUI. Я предполагаю, что это происходит из-за того, что он загружается из QSettings и почему-то не загружаются мои QtWidgets. Как я могу загрузить свои виджеты QT при сохранении кода активированным? : /

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)

edit: интересно, если я удаляю мой файл .ini, он отлично работает в первый раз. Я получаю эту ошибку:

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

Вот мой MainWindow пользовательского интерфейса. Я не добавил здесь никакого кода:

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)

Полный GUI код:

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

1 Ответ

2 голосов
/ 02 февраля 2020

Примечание: предупреждение вызвано ненужным введением PySide2, поэтому устранение импорта может решить эту проблему (я удалил его из публикации OP в издании, чтобы исключить ненужный импорт).


Проблема того, почему текст исчезает, заключается в том, что в коде функции «сохранить» сохраняются все свойства, а также сохранить нулевой QPixmap, который есть у QLabel, поэтому во время восстановления информации с помощью «восстановления» Функция сначала устанавливает текст, а затем QPixmap, так что вторая заменяет первую, так что это ограничение функций. Учитывая вышеизложенное, решение состоит в том, чтобы добавить больше фильтров, как показано ниже:

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))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...