在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

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值