• pyqt5的组合式部件制作(一)


            以多选一的选择器为例,来实践一下工程实用级别的组合式部件设计。自己之前做的自定义的组合式部件,结构不够简单优化,在实际的工程里面,使用部件的过程比较繁琐。所以,这里来做一个优化的实验。

            之所以做这个组合部件,而不用Qt Designer自带的QRadioButton,是因为我不会修改自带的QRadioButton,无法改变它的指示器圆点尺寸和颜色,我希望实现一些自定义的特殊效果和功能。

            这个部件的特点是有着若干个相同品种的子部件,但不确定数量。子部件由两部分组成:控制器和指示器,“就地控制”、“远程控制”、“自动运行”这几个文字标签构成了控制器,后面的方框是指示器。当点击控制器,指示器做出颜色状态改变,并发射信号。

    设计的目标:

            1、尽量在python程序里面不要手动逐个输入各个子部件的具体名称,因为当画面复杂时这将是一个很大的工作量。

            2、把部件做成模块,在Qt Designer里面可以简单ctrl+拖拽复制。

            3、当Qt Designer里面放置好部件以后,有简单的方法实现部件的自动或半自动初始化和特性定义。

    过程记录:

            1、Qt Designer里面新建一个QGroupBox作为容器部件,三个纯文字QLabel作为控制器,三个圆角矩形QLabel作为指示器。各个部件命名如下:

    父部件:_selector_1

    子部件:_control0_selector_1:选择器0

                   _control1_selector_1:选择器1

                   _control2_selector_1:选择器2

                   _state0_selector_1:指示器0

                   _state1_selector_1:指示器1

                   _state2_selector_1:指示器2

    命名的规律:需要自动运行初始化的自定义的组合部件首字母为"_ ",用以和其他不用初始化部件区分开(例如固定内容的文字标签、装饰用的线条之类的);子部件的名称的前半部分是子部件的分类和编号,如control0,后半部分是容器部件的名字,如selector_1,从命名上就可以看出子部件的功能以及它属于哪个容器部件;容器部件的最后一位数字是顺序号,当需要多个相同的容器部件时,直接ctrl+拖拽复制,顺序号就会自动递增。

    完成之后,将所有的子部件拖入容器部件,构成一个组合部件,如图:

    至此,前端工作告一段落,开始后端的编程。 

    2、自定义的QLabel

            由于默认的QLabel是不带鼠标事件的,需要自定义一下鼠标的进入、点击、释放、离开等各个事件。代码如下:

    1. from PyQt5.QtWidgets import QLabel
    2. from PyQt5.Qt import pyqtSignal
    3. class MyLabel(QLabel): # 自定义的Qlabel
    4. Entry = pyqtSignal() # 鼠标进入
    5. Leave = pyqtSignal() # 鼠标离开
    6. clicked = pyqtSignal() # 鼠标点击
    7. Release = pyqtSignal() # 鼠标释放
    8. def __init__(self, parent=None):
    9. super(MyLabel, self).__init__(parent)
    10. self.style_normal = None
    11. self.style_last = None
    12. self.style_on = None
    13. self.style_enter = None
    14. self.style_clicked = None
    15. self.Entry.connect(lambda: self.set_style(self.style_enter)) # 鼠标进入后改变样式表
    16. self.clicked.connect(lambda: self.set_style(self.style_clicked))
    17. self.Release.connect(lambda: self.set_style(self.style_last)) # 鼠标释放后改变样式表
    18. self.Leave.connect(lambda: self.set_style(self.style_last)) # 鼠标离开后改变样式表
    19. def init(self, style_normal='color: rgb(0, 0, 0);background-color: rgba(255, 255, 255, 0);',
    20. style_enter='border:1px solid #039806;border-radius:2px;background-color: rgba(194, 194, 194, 150);',
    21. style_clicked='border-radius:2px;background-color: rgba(194, 194, 194, 150);',
    22. style_on='border-radius:2px;background-color: #039806;border:2px solid #868686;border-radius:2px;'):
    23. self.style_normal = style_normal # 常态style
    24. self.style_enter = style_enter # 鼠标悬停后的style
    25. self.style_clicked = style_clicked # 鼠标点击后的style
    26. self.style_on = style_on
    27. def set_style(self, style):
    28. self.setStyleSheet(style)
    29. def mousePressEvent(self, event): # 重写鼠标点击事件
    30. self.clicked.emit() # 左单击
    31. def enterEvent(self, event): # 重新定义鼠标悬停事件
    32. self.style_last = self.styleSheet()
    33. self.Entry.emit()
    34. def leaveEvent(self, event): # 重新定义鼠标离开事件
    35. self.Leave.emit()
    36. def mouseReleaseEvent(self, event): # 重新定义鼠标释放事件mouseReleaseEvent
    37. self.Release.emit()

    代码里面有两个初始化函数__init__和init,第一个是默认在后台自动运行的初始化,第二个是需要在主程序里面运行一次的初始化,第二个初始化的目的是可以灵活定义一些特性,比如同一个项目中需要有不同背景颜色的同类部件,就可以根据需要单独修改相对应的参数来实现。

    将以上代码保存在主程序同文件夹下,并命名为MyLabel.py。

    回到Qt Designer,打开之前的ui文件,在画面空白处点右键:

     填写类和头文件的名称,然后点“添加”:

     在三个控制器上分别点右键,提升为,将其提升为刚刚自定义的QLabel:

    这样,控制器就基本完成了 。新建python文件,输入代码:

    1. from PyQt5 import uic
    2. from sys import exit, argv
    3. from PyQt5.QtWidgets import QApplication, QWidget
    4. if __name__ == '__main__':
    5. app = QApplication(argv)
    6. # 读取 UI 文件并转换为 Python 代码
    7. ui_file = '../UIS/test2.ui' # 更换为实际的ui文件地址
    8. form0 = uic.loadUi(ui_file) # 创建显示界面
    9. form0._control0_selector_1.init() # 部件的初始化
    10. form0._control1_selector_1.init()
    11. form0._control2_selector_1.init(style_enter='border:1px solid #868686;border-radius:2px;background-color: rgba(194, 56, 37, 200);') # 控制器的control2需要单独定义
    12. form0.show()
    13. exit(app.exec_())

    运行截图:

     可以看到,控制器control2由于采用了单独的init初始化参数,其显示效果是与默认的效果有区别的。这也正是自己制作部件的优势所在,你可以实现一些默认部件不具备的特殊效果和功能。

    下一步的任务是继续定义容器部件和指示器部件,以及实现预期的功能。

  • 相关阅读:
    C++ Qt关于启动可执行文件存在的问题
    Three.js——基础材质、深度材质、法向材质、面材质、朗伯材质、Phong材质、着色器材质、直线和虚线、联合材质
    IgH Master环境搭建
    商标未注册就使用,有什么后果?
    Django中的CSRF使用及ajax请求接口时问题总结
    数字IC前端学习笔记:数字乘法器的优化设计(基2布斯乘法器)
    【自定义列表头】vue el-table表格自定义列显示隐藏,多级表头自定义列显示隐藏,自由搭配版本和固定列版本【注释详细】
    【Matlab】常用函数汇总(一)
    前端开发规范的区别(Commonjs、AMD、CMD、ES6模块化)
    LLM.int8()——自适应混合精度量化方法
  • 原文地址:https://blog.csdn.net/xulibo5828/article/details/134261060