在用vnstation的时候, 很多地方都要用户手动输入, 很多场景下都希望能够保存上次输入内容. 这个控件可以解决. vnstation的任何界面都可以继承这两个组件, 实现恢复上次输入内容(原来是Qdialog的, 继承RestorableQDialog, 原来是Qwidget的, 继承RestorableQWidget, 在ui初始化之后, 调用self.load_settings()方法即可), 原理是用Qsetting储存这些配置到注册表.
from PySide6.QtCore import QSettings
from PySide6.QtWidgets import QApplication, QVBoxLayout, QLineEdit
from PySide6 import QtWidgets
def func(x, y):
y = set(y)
for i in y:
found = False
for j in range(x.count()):
if i == x.item(j).text():
found = True
break
if not found:
x.addItem(i)
SUPPORTED_TYPE = {
"line_edit": {"type_": QtWidgets.QLineEdit, "func_setValue": lambda x, y: x.setText(y),
"func_getValue": lambda x: x.text()},
"spinbox": {"type_": QtWidgets.QSpinBox, "func_setValue": lambda x, y: x.setValue(y),
"func_getValue": lambda x: x.value()},
"combobox": {"type_": QtWidgets.QComboBox, "func_setValue": lambda x, y: x.setCurrentText(y),
"func_getValue": lambda x: x.currentText()},
"radio_btn": {"type_": QtWidgets.QRadioButton, "func_setValue": lambda x, y: x.setChecked(y),
"func_getValue": lambda x: int(x.isChecked())},
"checkbox": {"type_": QtWidgets.QCheckBox, "func_setValue": lambda x, y: x.setChecked(y),
"func_getValue": lambda x: int(x.checkState())},
"list_widget": {"type_": QtWidgets.QListWidget, "func_setValue": func,
"func_getValue": lambda x: list(x.item(i).text() for i in range(x.count()))}
}
class RestorableQDialog(QtWidgets.QDialog):
COMPANY_NAME = "LXRestorableQDialog"
def __init__(self, window_name):
super().__init__()
self.window_name = window_name
def find_child(self):
found_widget_dict = {}
for group_name, d in SUPPORTED_TYPE.items():
widget_list = [widget for widget in self.findChildren(d["type_"]) if not widget.objectName()]
if widget_list:
found_widget_dict[group_name] = widget_list
return found_widget_dict
def save_settings(self, found_widget_dict):
settings = QSettings(self.COMPANY_NAME, self.window_name)
for group_name, widget_list in found_widget_dict.items():
get_func = SUPPORTED_TYPE[group_name].get("func_getValue")
settings.beginGroup(group_name)
for n, widget_ in enumerate(widget_list):
value = get_func(widget_)
settings.setValue(str(n), value)
settings.endGroup()
settings.sync()
def closeEvent(self, e):
super().closeEvent(e)
self.save_settings(self.find_child())
def accept(self) -> None:
self.save_settings(self.find_child())
super().accept()
def load_settings(self):
found_widget_dict = self.find_child()
settings = QSettings(self.COMPANY_NAME, self.window_name)
for group_name, widget_list in found_widget_dict.items():
settings.beginGroup(group_name)
for n, widget_ in enumerate(widget_list):
set_func = SUPPORTED_TYPE[group_name].get("func_setValue")
value = settings.value(str(n))
if value is not None:
set_func(widget_, value)
settings.endGroup()
class RestorableQWidget(QtWidgets.QWidget):
COMPANY_NAME = "LXRestorableQWidget"
def __init__(self, window_name):
super().__init__()
self.window_name = window_name
def find_child(self):
found_widget_dict = {}
for group_name, d in SUPPORTED_TYPE.items():
widget_list = [widget for widget in self.findChildren(d["type_"]) if not widget.objectName()]
if widget_list:
found_widget_dict[group_name] = widget_list
return found_widget_dict
def save_settings(self, found_widget_dict):
settings = QSettings(self.COMPANY_NAME, self.window_name)
for group_name, widget_list in found_widget_dict.items():
get_func = SUPPORTED_TYPE[group_name].get("func_getValue")
settings.beginGroup(group_name)
for n, widget_ in enumerate(widget_list):
value = get_func(widget_)
settings.setValue(str(n), value)
settings.endGroup()
settings.sync()
def closeEvent(self, e):
super().closeEvent(e)
self.save_settings(self.find_child())
def load_settings(self):
found_widget_dict = self.find_child()
settings = QSettings(self.COMPANY_NAME, self.window_name)
for group_name, widget_list in found_widget_dict.items():
settings.beginGroup(group_name)
for n, widget_ in enumerate(widget_list):
set_func = SUPPORTED_TYPE[group_name].get("func_setValue")
value = settings.value(str(n))
if value is not None:
set_func(widget_, value)
settings.endGroup()
class RestorableCustomQDialog(RestorableQDialog):
def __init__(self):
super().__init__(window_name=RestorableCustomQDialog.__name__)
layout = QVBoxLayout()
line_edit = QLineEdit()
line_edit2 = QLineEdit()
line_edit3 = QLineEdit()
spin = QtWidgets.QSpinBox()
btn = QtWidgets.QPushButton("accept")
btn.clicked.connect(self.accept)
layout.addWidget(line_edit)
layout.addWidget(line_edit2)
layout.addWidget(line_edit3)
layout.addWidget(spin)
layout.addWidget(btn)
self.setLayout(layout)
def show(self):
self.load_settings() # 在子类的show方法中调用load_settings()
super().show()
if __name__ == "__main__":
app = QApplication([])
widget = RestorableCustomQDialog()
widget.show()
app.exec()
用法:
例如回测界面的BacktestingSettingEditor
class BacktestingSettingEditor(RestorableQDialog):
"""
回测参数配置界面.
"""
def __init__(
self, class_name: str, parameters: dict
) -> None:
""""""
super(BacktestingSettingEditor, self).__init__(BacktestingSettingEditor.__name__)
self.class_name: str = class_name
self.parameters: dict = parameters
self.edits: dict = {}
self.init_ui()
self.load_settings()
修改super(BacktestingSettingEditor, self).init(BacktestingSettingEditor.name)
增加self.load_settings()
所有界面都可以用类似的办法实现restore用户输入内容
目前实现了6种常用组件的保存和恢复, 有pyqt基础的, 可以自行添加