• 在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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    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()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    3 注意

    在测试的时候,发现单独的执行,会报错。

    import yaml
    lily = yaml.load('!NewDeploy {}', Loader=yaml.Loader)
    print(lily)
    print(lily.button)
    
    • 1
    • 2
    • 3
    • 4

    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_())
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    注意: 装饰器一定要在init.py里写上,不然报错找不到,写上之后一定要import 不然也不回去init.py里加载

    比如registry_module 这个文件夹下的init.py里写上from .yaml_helpers import serializable

  • 相关阅读:
    docker-基本操作命令,生成docker镜像包
    6.1 KMP算法搜索机器码
    VUE设置和清除定时器
    基础课12——数据采集
    SonarQube的使用心得
    详细计算机专业毕业设计开题报告书写方法
    C语言之详解内存操作函数
    Python之导出项目所需要的依赖库,在线或离线安装
    arm-2d库详细介绍
    通过API接口进行商品价格监控,可以按照以下步骤进行操作
  • 原文地址:https://blog.csdn.net/qq_33228039/article/details/125623250