-
-
Save Zythyr/930ed8ac09a830717a459349e942a86a to your computer and use it in GitHub Desktop.
PyQt5 - Issue with using QSettings to save and restore widget settings
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os, sys, time, traceback | |
from PyQt5 import QtWidgets, uic, QtCore, QtGui | |
from PyQt5.QtCore import QFileInfo, QSettings | |
from PyQt5.QtWidgets import qApp | |
from ui_mainwindow import Ui_MainWindow | |
def settings_value_is_valid(val): | |
# https://stackoverflow.com/a/60028282/4988010 | |
if isinstance(val, QtGui.QPixmap): | |
return not val.isNull() | |
return True | |
def settings_restore(settings): | |
# https://stackoverflow.com/a/60028282/4988010 | |
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) | |
# print(prop, name, last_value, key) | |
if not settings.contains(key): | |
continue | |
val = settings.value(key, type=type(last_value),) | |
if ( | |
val != last_value | |
and settings_value_is_valid(val) | |
and prop.isValid() | |
and prop.isWritable() | |
): | |
w.setProperty(name, val) | |
def settings_save(settings): | |
# https://stackoverflow.com/a/60028282/4988010 | |
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 settings_value_is_valid(val) and prop.isValid() and prop.isWritable(): | |
settings.setValue(key, w.property(name)) | |
class MyApp(QtWidgets.QMainWindow): | |
def __init__(self): | |
super(MyApp, self).__init__() | |
self.settings = QSettings("./temp/gui_settings.ini", QSettings.IniFormat) | |
self.ui = Ui_MainWindow() | |
self.ui.setupUi(self) | |
self.ui.action_config_save_current_values.triggered.connect(self.config_widgets_save_settings) | |
self.ui.action_config_load_config_file.triggered.connect(self.config_widgets_load_settings) | |
self.ui.action_config_reset_to_factory_default.triggered.connect(self.config_widgets_reset_settings) | |
def config_widgets_save_settings(self): | |
# Save settings | |
# self.logger.info('Saving current values of the widgets into a config file.') | |
settings_save(self.settings) | |
def config_widgets_load_settings(self): | |
# self.logger.info('Loading saved widgets settings config file.') | |
# Load previous usage settings | |
settings_restore(self.settings) | |
def config_widgets_reset_settings(self): | |
# self.logger.info('Resetting the saved widgets settings config file to default factor settings.') | |
self.settings.clear() | |
self.ui.setupUi(self) | |
if __name__ == '__main__': | |
app = QtWidgets.QApplication(sys.argv) | |
# print(QtWidgets.QStyleFactory.keys()) | |
app.setStyle('Fusion') | |
window = MyApp() | |
window.show() | |
app.exec_() | |
# sys.exit(app.exec_()) | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="UTF-8"?> | |
<ui version="4.0"> | |
<class>MainWindow</class> | |
<widget class="QMainWindow" name="MainWindow"> | |
<property name="geometry"> | |
<rect> | |
<x>0</x> | |
<y>0</y> | |
<width>368</width> | |
<height>204</height> | |
</rect> | |
</property> | |
<property name="windowTitle"> | |
<string>MainWindow</string> | |
</property> | |
<widget class="QWidget" name="centralwidget"> | |
<widget class="QPushButton" name="start_button"> | |
<property name="geometry"> | |
<rect> | |
<x>100</x> | |
<y>80</y> | |
<width>109</width> | |
<height>23</height> | |
</rect> | |
</property> | |
<property name="styleSheet"> | |
<string notr="true">QPushButton::checked {background-color: #6cf090; }</string> | |
</property> | |
<property name="text"> | |
<string>Start</string> | |
</property> | |
<property name="checkable"> | |
<bool>false</bool> | |
</property> | |
</widget> | |
<widget class="QWidget" name="layoutWidget"> | |
<property name="geometry"> | |
<rect> | |
<x>10</x> | |
<y>10</y> | |
<width>342</width> | |
<height>51</height> | |
</rect> | |
</property> | |
<layout class="QGridLayout" name="gridLayout_2"> | |
<item row="0" column="0"> | |
<widget class="QLabel" name="label_10"> | |
<property name="text"> | |
<string>Param A</string> | |
</property> | |
</widget> | |
</item> | |
<item row="0" column="2"> | |
<widget class="QLabel" name="label_12"> | |
<property name="text"> | |
<string>Param C</string> | |
</property> | |
</widget> | |
</item> | |
<item row="0" column="1"> | |
<widget class="QLabel" name="label_11"> | |
<property name="text"> | |
<string>Param B</string> | |
</property> | |
</widget> | |
</item> | |
<item row="1" column="2"> | |
<widget class="QDoubleSpinBox" name="param_c"> | |
<property name="decimals"> | |
<number>3</number> | |
</property> | |
<property name="maximum"> | |
<double>100000000.000000000000000</double> | |
</property> | |
<property name="value"> | |
<double>1234.000000000000000</double> | |
</property> | |
</widget> | |
</item> | |
<item row="1" column="0"> | |
<widget class="QDoubleSpinBox" name="param_a"> | |
<property name="decimals"> | |
<number>3</number> | |
</property> | |
<property name="maximum"> | |
<double>9999.000000000000000</double> | |
</property> | |
<property name="singleStep"> | |
<double>0.050000000000000</double> | |
</property> | |
<property name="value"> | |
<double>1.500000000000000</double> | |
</property> | |
</widget> | |
</item> | |
<item row="1" column="1"> | |
<widget class="QDoubleSpinBox" name="param_b"> | |
<property name="decimals"> | |
<number>3</number> | |
</property> | |
<property name="maximum"> | |
<double>9999.000000000000000</double> | |
</property> | |
<property name="singleStep"> | |
<double>0.050000000000000</double> | |
</property> | |
<property name="value"> | |
<double>0.250000000000000</double> | |
</property> | |
</widget> | |
</item> | |
<item row="0" column="3"> | |
<widget class="QLabel" name="label_4"> | |
<property name="text"> | |
<string>Param D</string> | |
</property> | |
</widget> | |
</item> | |
<item row="1" column="3"> | |
<widget class="QSpinBox" name="param_d"> | |
<property name="maximum"> | |
<number>999999999</number> | |
</property> | |
<property name="value"> | |
<number>456</number> | |
</property> | |
</widget> | |
</item> | |
</layout> | |
</widget> | |
</widget> | |
<widget class="QMenuBar" name="menubar"> | |
<property name="geometry"> | |
<rect> | |
<x>0</x> | |
<y>0</y> | |
<width>368</width> | |
<height>21</height> | |
</rect> | |
</property> | |
<widget class="QMenu" name="menuFile"> | |
<property name="title"> | |
<string>File</string> | |
</property> | |
<widget class="QMenu" name="menuWidget_defaults"> | |
<property name="title"> | |
<string>Widget defaults</string> | |
</property> | |
<addaction name="action_config_save_current_values"/> | |
<addaction name="action_config_load_config_file"/> | |
<addaction name="action_config_reset_to_factory_default"/> | |
</widget> | |
<addaction name="menuWidget_defaults"/> | |
</widget> | |
<addaction name="menuFile"/> | |
</widget> | |
<widget class="QStatusBar" name="statusbar"/> | |
<action name="action_config_save_current_values"> | |
<property name="text"> | |
<string>Save current values</string> | |
</property> | |
</action> | |
<action name="action_config_load_config_file"> | |
<property name="text"> | |
<string>Load config file</string> | |
</property> | |
</action> | |
<action name="action_config_reset_to_factory_default"> | |
<property name="text"> | |
<string>Reset to factory default</string> | |
</property> | |
</action> | |
</widget> | |
<resources/> | |
<connections/> | |
</ui> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
# Form implementation generated from reading ui file 'main.ui' | |
# | |
# Created by: PyQt5 UI code generator 5.15.0 | |
# | |
# WARNING: Any manual changes made to this file will be lost when pyuic5 is | |
# run again. Do not edit this file unless you know what you are doing. | |
from PyQt5 import QtCore, QtGui, QtWidgets | |
class Ui_MainWindow(object): | |
def setupUi(self, MainWindow): | |
MainWindow.setObjectName("MainWindow") | |
MainWindow.resize(368, 204) | |
self.centralwidget = QtWidgets.QWidget(MainWindow) | |
self.centralwidget.setObjectName("centralwidget") | |
self.start_button = QtWidgets.QPushButton(self.centralwidget) | |
self.start_button.setGeometry(QtCore.QRect(100, 80, 109, 23)) | |
self.start_button.setStyleSheet("QPushButton::checked {background-color: #6cf090; }") | |
self.start_button.setCheckable(False) | |
self.start_button.setObjectName("start_button") | |
self.layoutWidget = QtWidgets.QWidget(self.centralwidget) | |
self.layoutWidget.setGeometry(QtCore.QRect(10, 10, 342, 51)) | |
self.layoutWidget.setObjectName("layoutWidget") | |
self.gridLayout_2 = QtWidgets.QGridLayout(self.layoutWidget) | |
self.gridLayout_2.setContentsMargins(0, 0, 0, 0) | |
self.gridLayout_2.setObjectName("gridLayout_2") | |
self.label_10 = QtWidgets.QLabel(self.layoutWidget) | |
self.label_10.setObjectName("label_10") | |
self.gridLayout_2.addWidget(self.label_10, 0, 0, 1, 1) | |
self.label_12 = QtWidgets.QLabel(self.layoutWidget) | |
self.label_12.setObjectName("label_12") | |
self.gridLayout_2.addWidget(self.label_12, 0, 2, 1, 1) | |
self.label_11 = QtWidgets.QLabel(self.layoutWidget) | |
self.label_11.setObjectName("label_11") | |
self.gridLayout_2.addWidget(self.label_11, 0, 1, 1, 1) | |
self.param_c = QtWidgets.QDoubleSpinBox(self.layoutWidget) | |
self.param_c.setDecimals(3) | |
self.param_c.setMaximum(100000000.0) | |
self.param_c.setProperty("value", 1234.0) | |
self.param_c.setObjectName("param_c") | |
self.gridLayout_2.addWidget(self.param_c, 1, 2, 1, 1) | |
self.param_a = QtWidgets.QDoubleSpinBox(self.layoutWidget) | |
self.param_a.setDecimals(3) | |
self.param_a.setMaximum(9999.0) | |
self.param_a.setSingleStep(0.05) | |
self.param_a.setProperty("value", 1.5) | |
self.param_a.setObjectName("param_a") | |
self.gridLayout_2.addWidget(self.param_a, 1, 0, 1, 1) | |
self.param_b = QtWidgets.QDoubleSpinBox(self.layoutWidget) | |
self.param_b.setDecimals(3) | |
self.param_b.setMaximum(9999.0) | |
self.param_b.setSingleStep(0.05) | |
self.param_b.setProperty("value", 0.25) | |
self.param_b.setObjectName("param_b") | |
self.gridLayout_2.addWidget(self.param_b, 1, 1, 1, 1) | |
self.label_4 = QtWidgets.QLabel(self.layoutWidget) | |
self.label_4.setObjectName("label_4") | |
self.gridLayout_2.addWidget(self.label_4, 0, 3, 1, 1) | |
self.param_d = QtWidgets.QSpinBox(self.layoutWidget) | |
self.param_d.setMaximum(999999999) | |
self.param_d.setProperty("value", 456) | |
self.param_d.setObjectName("param_d") | |
self.gridLayout_2.addWidget(self.param_d, 1, 3, 1, 1) | |
MainWindow.setCentralWidget(self.centralwidget) | |
self.menubar = QtWidgets.QMenuBar(MainWindow) | |
self.menubar.setGeometry(QtCore.QRect(0, 0, 368, 21)) | |
self.menubar.setObjectName("menubar") | |
self.menuFile = QtWidgets.QMenu(self.menubar) | |
self.menuFile.setObjectName("menuFile") | |
self.menuWidget_defaults = QtWidgets.QMenu(self.menuFile) | |
self.menuWidget_defaults.setObjectName("menuWidget_defaults") | |
MainWindow.setMenuBar(self.menubar) | |
self.statusbar = QtWidgets.QStatusBar(MainWindow) | |
self.statusbar.setObjectName("statusbar") | |
MainWindow.setStatusBar(self.statusbar) | |
self.action_config_save_current_values = QtWidgets.QAction(MainWindow) | |
self.action_config_save_current_values.setObjectName("action_config_save_current_values") | |
self.action_config_load_config_file = QtWidgets.QAction(MainWindow) | |
self.action_config_load_config_file.setObjectName("action_config_load_config_file") | |
self.action_config_reset_to_factory_default = QtWidgets.QAction(MainWindow) | |
self.action_config_reset_to_factory_default.setObjectName("action_config_reset_to_factory_default") | |
self.menuWidget_defaults.addAction(self.action_config_save_current_values) | |
self.menuWidget_defaults.addAction(self.action_config_load_config_file) | |
self.menuWidget_defaults.addAction(self.action_config_reset_to_factory_default) | |
self.menuFile.addAction(self.menuWidget_defaults.menuAction()) | |
self.menubar.addAction(self.menuFile.menuAction()) | |
self.retranslateUi(MainWindow) | |
QtCore.QMetaObject.connectSlotsByName(MainWindow) | |
def retranslateUi(self, MainWindow): | |
_translate = QtCore.QCoreApplication.translate | |
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) | |
self.start_button.setText(_translate("MainWindow", "Start")) | |
self.label_10.setText(_translate("MainWindow", "Param A")) | |
self.label_12.setText(_translate("MainWindow", "Param C")) | |
self.label_11.setText(_translate("MainWindow", "Param B")) | |
self.label_4.setText(_translate("MainWindow", "Param D")) | |
self.menuFile.setTitle(_translate("MainWindow", "File")) | |
self.menuWidget_defaults.setTitle(_translate("MainWindow", "Widget defaults")) | |
self.action_config_save_current_values.setText(_translate("MainWindow", "Save current values")) | |
self.action_config_load_config_file.setText(_translate("MainWindow", "Load config file")) | |
self.action_config_reset_to_factory_default.setText(_translate("MainWindow", "Reset to factory default")) | |
if __name__ == "__main__": | |
import sys | |
app = QtWidgets.QApplication(sys.argv) | |
MainWindow = QtWidgets.QMainWindow() | |
ui = Ui_MainWindow() | |
ui.setupUi(MainWindow) | |
MainWindow.show() | |
sys.exit(app.exec_()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment