For an older application, it implements the functions that saved the states of the widgets and restored them.
In order for it to work properly, the application must meet the following requirements:
You have to set OrganizationName
, OrganizationDomain
and ApplicationName
.
Each widget that you want to save the state must have an objectName
You must use restore()
when you want to restore the states, a good option is after creating all the widgets.
You must use save()
when you want to save the states, a good place would be closeEvent()
.
In the next part I show an example:
import sys
from PyQt5 import QtWidgets, QtCore
# for PyQt4 change QtWidget to QtGui and PyQt5 to PyQt4
def restore(settings):
finfo = QtCore.QFileInfo(settings.fileName())
if finfo.exists() and finfo.isFile():
for w in QtWidgets.qApp.allWidgets():
mo = w.metaObject()
if w.objectName() and not w.objectName().startswith("qt_"):
settings.beginGroup(w.objectName())
for i in range( mo.propertyCount(), mo.propertyOffset()-1, -1):
prop = mo.property(i)
if prop.isWritable():
name = prop.name()
val = settings.value(name, w.property(name))
if str(val).isdigit():
val = int(val)
w.setProperty(name, val)
settings.endGroup()
def save(settings):
for w in QtWidgets.qApp.allWidgets():
mo = w.metaObject()
if w.objectName() and not w.objectName().startswith("qt_"):
settings.beginGroup(w.objectName())
for i in range(mo.propertyCount()):
prop = mo.property(i)
name = prop.name()
if prop.isWritable():
settings.setValue(name, w.property(name))
settings.endGroup()
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setObjectName("widget")
self.init_ui()
self.settings = QtCore.QSettings()
print(self.settings.fileName())
restore(self.settings)
def init_ui(self):
lay = QtWidgets.QVBoxLayout(self)
lineEdit1 = QtWidgets.QLabel("label")
lineEdit1.setObjectName("label")
lineEdit2 = QtWidgets.QLineEdit()
lineEdit2.setObjectName("lineEdit2")
combobox = QtWidgets.QComboBox()
combobox.addItems(["1", "2", "3"])
combobox.setObjectName("combo")
lay.addWidget(lineEdit1)
lay.addWidget(lineEdit2)
lay.addWidget(combobox)
def closeEvent(self, event):
save(self.settings)
super().closeEvent(event)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
QtCore.QCoreApplication.setOrganizationName("Eyllanesc")
QtCore.QCoreApplication.setOrganizationDomain("eyllanesc.com")
QtCore.QCoreApplication.setApplicationName("MyApp")
ex = Widget()
ex.show()
sys.exit(app.exec_())
Update:
In the case that you use Qt Designer it is no longer necessary to place the objectsName
s because they are already established, but on the other hand the class that provides Qt Designer is not a widget, but a class that is responsible for filling a widget, so we must create the widget to be able to overwrite the closeEvent
method as shown below:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
...
def retranslateUi(self, MainWindow):
...
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setupUi(self)
self.settings = QtCore.QSettings()
restore(self.settings)
def closeEvent(self, event):
save(self.settings)
super().closeEvent(event)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
QtCore.QCoreApplication.setOrganizationName("Eyllanesc")
QtCore.QCoreApplication.setOrganizationDomain("eyllanesc.com")
QtCore.QCoreApplication.setApplicationName("MyApp")
w = MainWindow()
w.show()
sys.exit(app.exec_())
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…