在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 实例化类的主要内容,如果未能解决你的问题,请参考以下文章

TypeScript 回调没有在其签名中完全实例化类

在不使用 STL 的情况下,在 C++ 中存储和实例化类列表的最佳方法是啥?

在 C++ 中使用字符串到类查找表来实例化类

查找是不是可以使用一组参数实例化类模板,arity-wise(在 C++17 中)

在实例化类之前在 Python 类中定义的方法的正确术语是啥?

在Java中获取参数化类的实例[重复]