当前位置: 首页 > news >正文

pyQt实现一种按钮切换关联变化的勾选框的逻辑

本篇使用python来实现一种按钮切换关联变化的勾选框的逻辑。

1 功能说明

假设一种产品有多个型号,每个型号有各自不同的功能,想要通过一个界面,来展示不同型号的不同功能。

型号是一种单选按钮的型号,每次只能选择其中一种型号。

功能通过勾选框的方式展示,可以多选需要的功能。

2 代码实现

对于上述需要,通过pyQt来实现界面以及界面中的控件:

  • 对于单选按钮,使用QRadioButton组件
  • 对于勾选框,使用QCheckBox组件
  • 对于将一类组件集合为一个组展示,使用QGroupBox组件
  • 对于每组内组件的水平与垂直布局,使用 QHBoxLayout与 QVBoxLayout布局

组件有了之后,如何实现型号切换后,对于的功能进行对应的展示,是一个关键点,下面给出思路:

  • 首先是创建出所有型号的所有功能的checkbox组件,结合其名称,存放到一个python的字典结构中
  • 初始显示时(默认选择了一个型号),根据选中的型号的产品功能,将对应的checkbox组件添加到界面布局中
  • 当型号切换后,则将界面布局中的原有的checkbox组件都先移除,然后将切换后型号的产品功能对应的checkbox组件添加到界面布局中

2.1 初始化

型号的类别,以及对应的功能,使用python的字典(dictionary)数据结构来定义,如代码中的 self.model_funcs.

字典是一种键值对(key-value)结构的数据类型,使用大括号 {} 表示,其中:

  • 键(key)是唯一的,这里的键是 "型号1""型号2"
  • 值(value)可以是任何数据类型,这里的值是列表(list),包含了各个型号对应的功能

字典这种数据结构非常适合表示具有映射关系的数据.

列表(list)是一种有序、可变的序列数据类型,用于存储多个元素的集合。它的主要特点和常用操作如下:

  • 用方括号 [] 定义,元素之间用逗号分隔
  • 元素可以是不同的数据类型(整数、字符串、列表等)
  • 支持索引访问(从 0 开始)和切片操作
  • 长度可变,可动态添加 / 删除元素
    def __init__(self):super().__init__()self.model_funcs = {"型号1" : ["功能A", "功能B", "功能C"],"型号2" : ["功能C", "功能D"]}self.model_radio_button = {}self.func_checkboxes = {}self.init_ui()

下面是具体的界面初始化代码,首先是型号的实现逻辑:

  • model_layout定义一个水平布局,QRadioButton通过model_layout.addWidget(radio)的方式,实现按钮的水平排列
  • model_group定义一个组,通过model_group.setLayout(model_layout)的方式,将水平排列的按钮添加到组中
  • 型号的名称,通过遍历self.model_funcs.keys(),创建对应的按钮: radio = QRadioButton(model_name)
  • 将radio组件及名称记录到self.model_radio_button字典中
  • 按钮的切换,通过关联槽函数radio.clicked.connect(self.on_model_changed),实现按钮切换后的逻辑处理
    def init_ui(self):# 型号水平布局,并集中到一个型号组中model_layout = QHBoxLayout()for i, model_name in enumerate(self.model_funcs.keys()):logger.info(f"i:{i}, model_name:{model_name}")radio = QRadioButton(model_name)# 默认第0个型号被选中if i == 0:radio.setChecked(True)# 给每个型号的radio连接槽函数radio.clicked.connect(self.on_model_changed)# 将radio组件添加到布局model_layout.addWidget(radio)# 将radio组件及名称记录到self.model_radio_button[]中self.model_radio_button[model_name] = radiomodel_group = QGroupBox("型号")model_group.setLayout(model_layout)

然后是功能点的实现逻辑:

  • self.funcs_layout定义一个垂直布局,注意这里前面加了一个self,因为在该类的其它函数中需要跨函数使用
  • funcs_group定义了一个组,布局逻辑和上面的型号的布局类似
  • all_funcs定义了一个集合(set),它是一种无序、不重复的元素集合,属于可变数据类型,主要特点如下:
    • 用大括号 {} 定义(注意:空集合不能用 {} 定义,需用 set()
    • 元素必须是不可变类型(如整数、字符串、元组等),不能包含列表、字典等可变类型
    • 自动去重,集合中不会有重复的元素
    • 无序性,不支持索引访问,不能通过位置获取元素
  • 使用集合,是为了去除不同型号的功能点的重复数据,通过遍历self.model_funcs.values(),并通过all_funcs.update(func)的方式,得到没有重复的功能点
  • 然后遍历all_funcs,创建勾选框组件checkbox = QCheckBox(func),再将组件添加到self.func_checkboxes字典中
        # 功能点垂直布局,并集中到一个功能组中self.funcs_layout = QVBoxLayout()funcs_group = QGroupBox("功能")funcs_group.setLayout(self.funcs_layout)# 根据self.model_funcs中的定义,提取出非重复的所有功能点all_funcs = set()for func in self.model_funcs.values():all_funcs.update(func)# 创建所有功能点的checkboxfor func in sorted(all_funcs):logger.info(f"func:{func}")checkbox = QCheckBox(func)# 将checkbox组件及名称暂存到self.checkboxs[]中self.func_checkboxes[func] = checkbox

初始化显示默认型号对应的功能,默认型号是第1个,即“型号1”,其名称可通过list(self.model_funcs.keys())[0] 来获取。

功能展示的逻辑通过self.update_funcs_show函数实现,后面介绍。

        # 初始化显示默认型号对应的功能logger.info(f"list(self.model_funcs.keys())[0]:{list(self.model_funcs.keys())[0]}")self.update_funcs_show(list(self.model_funcs.keys())[0])

主布局,是垂直结构,上面是型号组,下面是功能组

        # 主布局main_layout = QVBoxLayout(self)main_layout.addWidget(model_group)main_layout.addWidget(funcs_group)

2.2 按钮切换的槽函数

逻辑如下:

  • 遍历self.model_radio_button字典,检查对应的按钮是否被按下
  • 若被按下,则调用self.update_funcs_show函数更新对应型号的功能点的展示
    # 切换型号def on_model_changed(self):# 遍历model_radio_buttonfor model_name, radio in self.model_radio_button.items():logger.debug(f"judge model_name:{model_name} ...")if radio.isChecked():logger.debug(f"model_name:{model_name} isChecked")self.update_funcs_show(model_name)break

2.3 根据型号和更新显示对应的功能

功能点的展示逻辑:

  • 先清除布局中的checkbox组件,通过判断布局中组件的个数self.funcs_layout.count(),若非0,说明存在组件
  • 然后通过self.funcs_layout.takeAt(0)来循环移除第一个checkbox组件
  • 然后再根据型号,遍历对应的功能点for func in self.model_funcs[model_name],将checkbox组件添加回布局中
    # 根据型号和更新显示对应的功能def update_funcs_show(self, model_name):logger.debug(f"model_name:{model_name}")# 先清除logger.debug(f"funcs_layout.count:{self.funcs_layout.count()}")while self.funcs_layout.count():child = self.funcs_layout.takeAt(0)if child.widget():logger.debug(f"remove child:{child}")child.widget().setParent(None)# 再添加for func in self.model_funcs[model_name]:logger.debug(f"add func:{func}")# 将checkbox组件添加到布局self.funcs_layout.addWidget(self.func_checkboxes[func])

2.4 完整代码

完整的代码如下,这里使用的是PySide6(PyQt的一种替代库,使用逻辑基本是通用的),并通过loguru模块实现log调试。

import sys
from loguru import logger
from PySide6.QtWidgets import (QApplication, QWidget, QVBoxLayout, QHBoxLayout,QRadioButton, QCheckBox, QGroupBox, QButtonGroup)class ModelSelect(QWidget):def __init__(self):super().__init__()self.model_funcs = {"型号1" : ["功能A", "功能B", "功能C"],"型号2" : ["功能C", "功能D"]}self.model_radio_button = {}self.func_checkboxes = {}self.init_ui()def init_ui(self):# 型号水平布局,并集中到一个型号组中model_layout = QHBoxLayout()for i, model_name in enumerate(self.model_funcs.keys()):logger.info(f"i:{i}, model_name:{model_name}")radio = QRadioButton(model_name)# 默认第0个型号被选中if i == 0:radio.setChecked(True)# 给每个型号的radio连接槽函数radio.clicked.connect(self.on_model_changed)# 将radio组件添加到布局model_layout.addWidget(radio)# 将radio组件及名称记录到self.model_radio_button[]中self.model_radio_button[model_name] = radiomodel_group = QGroupBox("型号")model_group.setLayout(model_layout)# 功能点垂直布局,并集中到一个功能组中self.funcs_layout = QVBoxLayout()funcs_group = QGroupBox("功能")funcs_group.setLayout(self.funcs_layout)# 根据self.model_funcs中的定义,提取出非重复的所有功能点all_funcs = set()for func in self.model_funcs.values():all_funcs.update(func)# 创建所有功能点的checkboxfor func in sorted(all_funcs):logger.info(f"func:{func}")checkbox = QCheckBox(func)# 将checkbox组件及名称暂存到self.checkboxs[]中self.func_checkboxes[func] = checkbox# 初始化显示默认型号对应的功能logger.info(f"list(self.model_funcs.keys())[0]:{list(self.model_funcs.keys())[0]}")self.update_funcs_show(list(self.model_funcs.keys())[0])# 主布局main_layout = QVBoxLayout(self)main_layout.addWidget(model_group)main_layout.addWidget(funcs_group)# 切换型号def on_model_changed(self):# 遍历model_radio_buttonfor model_name, radio in self.model_radio_button.items():logger.debug(f"judge model_name:{model_name} ...")if radio.isChecked():logger.debug(f"model_name:{model_name} isChecked")self.update_funcs_show(model_name)break# 根据型号和更新显示对应的功能def update_funcs_show(self, model_name):logger.debug(f"model_name:{model_name}")# 先清除logger.debug(f"funcs_layout.count:{self.funcs_layout.count()}")while self.funcs_layout.count():child = self.funcs_layout.takeAt(0)if child.widget():logger.debug(f"remove child:{child}")child.widget().setParent(None)# 再添加for func in self.model_funcs[model_name]:logger.debug(f"add func:{func}")# 将checkbox组件添加到布局self.funcs_layout.addWidget(self.func_checkboxes[func])if __name__ == "__main__":app = QApplication(sys.argv)window = ModelSelect()window.show()sys.exit(app.exec())

运行的打印如下,对应的界面就是文章开头的界面.

3总结

本篇使用python来实现了一种按钮切换关联变化的勾选框的逻辑,首先介绍了功能,然后逐步分析代码的实现逻辑,最后给出运行效果。

http://www.dtcms.com/a/442709.html

相关文章:

  • 网站设计要先做图么网站建设为中心
  • Doris专题1- 什么是Doris
  • Linux文件系统---软硬连接
  • 如何建立商城网站拼团小程序制作平台
  • 火车头wordpress建站群网站移动站
  • 【51单片机32个灯,第一次亮1,2。第二次亮2,3。第三次亮3,4。。。。】2023-2-10
  • 【LangChain】P12 LangChain 提示词模板深度解析(三):实例化参数
  • 智能数据交换系统:内涵、架构、优化与发展趋势
  • 手机金融界网站网站单页是什么意思
  • 14.伪修复提交与来自“收容所”的坐标
  • 余姚做网站哪家好北京市工程信息网
  • 如何构建汽车电子与芯片半导体行业的一体化质量堡垒:全星质量管理QMS系统功能分析
  • 常微分方程万能解的形式
  • 专门做美剧的网站咸宁手机网站建设
  • sed使用手册
  • 网站开发搭建ssc p2p 互助做网站第一步做什么
  • 做教育网站有什么好处搜狗推广
  • 成品网站模板源码 网站源码模板 html源码下载
  • Scrapy 框架深度解析:架构、组件与工作流程
  • 网站例子谷歌搜索引擎免费
  • 深圳专业设计网站平台做网站为什么可以自学
  • Ruby CGI 编程
  • 【数形结合】当天先到者等未到者20分钟,见面概率
  • 广州广告制作有限公司优化工具 wordpress
  • 企业网站建设需要费用什么是4c品牌建设模型
  • 专门做简历的网站有哪些网站建设社区交流
  • 网站备案有什么要求吗html5开发手机网站
  • YOLO入门教程(番外):卷积神经网络—图像卷积
  • 上海网站开发开发好的公司网站网站建设考虑要素
  • 有用的LOGO设计集锦