在pyqt中使用yaml 实例化类
Posted 东东就是我
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在pyqt中使用yaml 实例化类相关的知识,希望对你有一定的参考价值。
写在前面,本来希望通过yaml保存pyqt页面的类,但是弄完才发现,yaml解析类的时候不能解析复杂了pqyt控件类,白瞎了这么好用的配置。。。。。。。。。。
上篇文章写了paddledetection中yaml实例化的例子,现在我们把这个技术用在自己的项目中
1.yaml实例化函数
import inspect
import yaml
__all__ = ['serializable' ]
def _make_python_constructor(cls):
def python_constructor(loader, node):
if isinstance(node, yaml.SequenceNode):
args = loader.construct_sequence(node, deep=True)
return cls(*args)
else:
kwargs = loader.construct_mapping(node, deep=True)
try:
return cls(**kwargs)
except Exception as ex:
print("Error when construct instance from yaml config".
format(cls.__name__))
raise ex
return python_constructor
def _make_python_representer(cls):
# python 2 compatibility
if hasattr(inspect, 'getfullargspec'):
argspec = inspect.getfullargspec(cls)
else:
argspec = inspect.getfullargspec(cls.__init__)
argnames = [arg for arg in argspec.args if arg != 'self']
def python_representer(dumper, obj):
if argnames:
data = name: getattr(obj, name) for name in argnames
else:
data = obj.__dict__
if '_id' in data:
del data['_id']
return dumper.represent_mapping(u'!'.format(cls.__name__), data)
return python_representer
def serializable(cls):
"""
Add loader and dumper for given class, which must be
"trivially serializable"
Args:
cls: class to be serialized
Returns: cls
"""
yaml.add_constructor(u'!'.format(cls.__name__),
_make_python_constructor(cls))
yaml.add_representer(cls, _make_python_representer(cls))
return cls
2.在pqyt的类上添加装饰器
from UI.newdeploy import Ui_NewDeploy
from PyQt5 import QtWidgets
import json
import time
from .registry import New_Module
from .yaml_helpers import serializable
@serializable
@New_Module.register_module()
class NewDeploy(QtWidgets.QWidget, Ui_NewDeploy):
def __init__(self):
super(NewDeploy, self).__init__()
self.setupUi(self)
self.connect()
self.status = "初始化"
self.time = time.strftime('%Y-%m-%d %H:%M:%S')
self.button = ["打开", "转化", "删除"]
self.model_size = "10M"
# 读取配置文件
with open("modelconf.json", encoding="utf-8") as f:
self.model_inf = json.load(f)
self.init_data()
3 注意
在测试的时候,发现单独的执行,会报错。
import yaml
lily = yaml.load('!NewDeploy ', Loader=yaml.Loader)
print(lily)
print(lily.button)
yaml.constructor.ConstructorError: could not determine a constructor for the tag ‘!NewDeploy’
in “”, line 1, column 1:
!NewDeploy
开始我以为是类没有加载到yaml的构造器里,所以我import yaml的构造器,发现还是不对,经过大量测试,发现继承pyqt的类需要 app = QtWidgets.QApplication(sys.argv) 才可以实例化
import sys
from PyQt5 import QtWidgets
from registry_module import *
import yaml
global tem_tableland, new_logic, button_list
class MainWindow(object):
def __init__(self):
lily = yaml.load('!NewDeploy ', Loader=yaml.Loader)
print(lily)
print(lily.button)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
main_window = MainWindow()
sys.exit(app.exec_())
注意: 装饰器一定要在init.py里写上,不然报错找不到,写上之后一定要import 不然也不回去init.py里加载
比如registry_module 这个文件夹下的init.py里写上from .yaml_helpers import serializable
以上是关于在pyqt中使用yaml 实例化类的主要内容,如果未能解决你的问题,请参考以下文章
在不使用 STL 的情况下,在 C++ 中存储和实例化类列表的最佳方法是啥?
查找是不是可以使用一组参数实例化类模板,arity-wise(在 C++17 中)