使用PySide6/PyQt6实现全国省市区的级联选择组件

news/2025/9/22 16:00:38/文章来源:https://www.cnblogs.com/wuhuacong/p/19105392

使用PySide6/PyQt6实现全国省市区的级联选择组件

在基于BS或者H5实现全国省市区的级联选择组件,相对比较容易,一般都要有现成的封装,如对于移动端H5或者小程序的Vant4界面库,他们直接安装使用内置的数据即可进行调用。参考对应组件的数据,我们可以使用PySide6/PyQt6实现全国省市区的级联选择组件案例。

1、Vant4界面库使用的省市区组件数据

如参考Vant4的Area省市区选择组件:https://vant-ui.github.io/vant/#/zh-CN/area

image

 Vant 提供了一份中国省市区数据,你可以安装 @vant/area-data npm 包来引入即可使用,跟踪其使用的代码,可以看到对应的全国省市区的数据集合。

image

 

2、使用PySide6/PyQt6实现全国省市区的级联选择组件案例

参考对应组件的数据,我们可以使用PySide6/PyQt6实现全国省市区的级联选择组件案例,首先我们根据上面的数据集合,定义一个JSON文件,用于Python组件进行加载的数据源。

我们来构建一个全国86编码下的省份集合,如下所示。

image

对应省份下的城市,城市下的分区,分区下的乡镇,都可以如此遍历下去。

image

 这样就构建一个多级遍历的集合,可以无穷层级下去(如果必要的话)。

我们要加载这个JSON文件,在Python中很简单,使用json.load即可。

    region_data = {"86": {"110000": "北京市","120000": "天津市",},"110000": {"110100": "市辖区"},}# 加载数据region_file = "china_area_data.json"data_file_path = path.join(path.dirname(__file__), region_file)with open(data_file_path, "r", encoding="utf-8") as f:region_data = json.load(f)

主要的界面逻辑,就是动态生成省市区的标签和下拉组件,并结合事件进行级联的处理操作。

        layout = QHBoxLayout(self)# 动态创建多层级 ComboBoxfor i in range(levels):box_layout = QHBoxLayout()label = QLabel(self.labels[i] + ":")combo = QComboBox()box_layout.addWidget(label, 0)box_layout.addWidget(combo, 0)layout.addLayout(box_layout)self.combo_boxes.append(combo)# 绑定事件
            combo.currentIndexChanged.connect(lambda idx, level=i: self.on_selection_changed(level, idx))

上面代码就是构建多级的显示名称和下拉组件,在触发选择的事件后,更新下一级控件(下拉列表)的数据集合即可。

    def on_selection_changed(self, level, index):"""当某一层选择变化时,更新下级"""if index < 0:returncode = self.combo_boxes[level].itemData(index)# 更新下一层if level + 1 < self.levels:self.populate_level(level + 1, code)# 更新结果
        self.update_result()# 发射信号self.selectionChanged.emit(self.get_selection())

其中的selectionChanged的信号事件,是我们为自定义类定义的一个信号变量。

class CascadeSelector(QWidget):selectionChanged = Signal(list)   # 信号,传递选中的 (code, name) 列表

通过它的绑定处理,我们就可以在调用代码中获得选择的集合。

    region_data = {"86": {"110000": "北京市","120000": "天津市",},"110000": {"110100": "市辖区"},}# 加载数据region_file = "china_area_data.json"data_file_path = path.join(path.dirname(__file__), region_file)with open(data_file_path, "r", encoding="utf-8") as f:region_data = json.load(f)win = CascadeSelector(region_data, root_code="86", levels=3, labels=["省", "市", "区"])# 主界面绑定信号win.selectionChanged.connect(lambda sel: print("主界面收到:", sel))win.resize(400, 200)win.show()

运行界面效果,如下所示。

image

通过初始化自定义组件 CascadeSelector ,我们就可以实现类似省市区等多层级的数据级联选择的处理效果。

CascadeSelector组件的完整代码如下所示。
import sys
import json
from PySide6.QtWidgets import (QApplication, QWidget, QVBoxLayout, QComboBox, QLabel, QHBoxLayout
)
from PySide6.QtCore import Signalfrom os import path
from pathlib import Pathclass CascadeSelector(QWidget):selectionChanged = Signal(list)   # 信号,传递选中的 (code, name) 列表def __init__(self, data, root_code="86", levels=3, labels=None, parent=None):""":param data: 行政区划映射数据 (dict):param root_code: 起始父节点 (默认 "86" -> 全国):param levels: 层级数量 (如 3 = 省、市、区):param labels: 每层的提示文字 (如 ["省", "市", "区"])"""super().__init__(parent)self.data = dataself.root_code = root_codeself.levels = levelsself.labels = labels or [f"Level{i+1}" for i in range(levels)]self.combo_boxes :list[QComboBox] = []layout = QHBoxLayout(self)# 动态创建多层级 ComboBoxfor i in range(levels):box_layout = QHBoxLayout()label = QLabel(self.labels[i] + ":")combo = QComboBox()box_layout.addWidget(label, 0)box_layout.addWidget(combo, 0)layout.addLayout(box_layout)self.combo_boxes.append(combo)# 绑定事件
            combo.currentIndexChanged.connect(lambda idx, level=i: self.on_selection_changed(level, idx))layout.addStretch(1)# 结果显示# self.result_label = QLabel("选择结果:")# layout.addWidget(self.result_label)# 初始化第一级
        self.populate_level(0, self.root_code)def populate_level(self, level, parent_code):"""填充某一层级的 ComboBox"""if level >= self.levels:returncombo : QComboBox = self.combo_boxes[level]combo.blockSignals(True)combo.clear()children = self.data.get(parent_code, {})for code, name in children.items():combo.addItem(name, code)combo.blockSignals(False)# 自动联动下一层if combo.count() > 0:self.on_selection_changed(level, 0)def on_selection_changed(self, level, index):"""当某一层选择变化时,更新下级"""if index < 0:returncode = self.combo_boxes[level].itemData(index)# 更新下一层if level + 1 < self.levels:self.populate_level(level + 1, code)# 更新结果
        self.update_result()# 发射信号
        self.selectionChanged.emit(self.get_selection())def update_result(self):names = [cb.currentText() for cb in self.combo_boxes if cb.currentIndex() >= 0]# self.result_label.setText("选择结果:" + " - ".join(names))def get_selection(self):"""获取完整的选择结果 (code 和 name)"""result = []for cb in self.combo_boxes:cb:QComboBoxidx = cb.currentIndex()if idx >= 0:result.append((cb.itemData(idx), cb.currentText()))return result# -------------------- 测试 --------------------
if __name__ == "__main__":app = QApplication(sys.argv)# 模拟数据(和你给的格式一致)region_data = {"86": {"110000": "北京市","120000": "天津市",},"110000": {"110100": "市辖区"},"110100": {"110101": "东城区","110102": "西城区","110105": "朝阳区","110106": "丰台区","110107": "石景山区","110108": "海淀区","110109": "门头沟区","110111": "房山区","110112": "通州区","110113": "顺义区","110114": "昌平区","110115": "大兴区","110116": "怀柔区","110117": "平谷区","110118": "密云区","110119": "延庆区"},"120000": {"120100": "市辖区"},"120100": {"120101": "和平区","120102": "河东区","120103": "河西区","120104": "南开区","120105": "河北区","120106": "红桥区","120110": "东丽区","120111": "西青区","120112": "津南区","120113": "北辰区","120114": "武清区","120115": "宝坻区","120116": "滨海新区","120117": "宁河区","120118": "静海区","120119": "蓟州区"},}# 加载数据region_file = "china_area_data.json"data_file_path = path.join(path.dirname(__file__), region_file)with open(data_file_path, "r", encoding="utf-8") as f:region_data = json.load(f)win = CascadeSelector(region_data, root_code="86", levels=3, labels=["", "", ""])# 主界面绑定信号win.selectionChanged.connect(lambda sel: print("主界面收到:", sel))win.resize(400, 200)win.show()sys.exit(app.exec())

通过这样,我们把自定义组件作为一个界面元素,可以放在任何需要的地方呈现,实现了数据的封装,并获得事件的信号处理即可。

image

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/909564.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WPF TextBlock effect DropShadrowEffect,BlurEffect

<Window x:Class="WpfApp32.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d=&quo…

重庆建设集团网站企业建设流程

目录 一、动态顺序表结构定义 二、动态顺序表初始化 三、动态顺序表打印 四、动态顺序表尾插 五、封装扩容函数 六、动态顺序表头插 七、动态顺序表的尾删 八、动态顺序表的头删 九、动态顺序表任意位置插入 十、动态顺序表任意位置删除 十一、动态顺序表销毁 十二、…

求网站建设贵阳电商网站建设

一:论语 这个有意思,我们可以从中得出的是&#xff0c;一个人过错 其实是潜意思决定的 行为见品质 但知错更改也是nice的 二:题目 三:上码 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* Tr…

服务周到的微网站建设wordpress地理定位

精简jdk包帖子“ 紧凑数字格式出现在JDK 12中 ”演示了对JDK 12中 NumberFormat的支持&#xff0c;以支持紧凑数字格式 。 该帖子中显示的示例仅使用NumberFormat的实例&#xff0c;这些实例是通过调用NumberFormat的新重载getCompactNumberInstance(-)方法返回的&#xff0c;因…

做网站广告公司国外销售网站怎样建设

1.使用 typeof bar “object” 判断 bar 是不是一个对象有神马潜在的弊端&#xff1f;如何避免这种弊端&#xff1f;使用 typeof 的弊端是显而易见的(这种弊端同使用 instanceof)&#xff1a;let obj {};let arr [];console.log(typeof obj object); //trueconsole.log(typ…

开发购物平台网站费用网站关键词被改

目录 一、规则 二、方法 1、seed 2、identifier 1&#xff09;选取一个身份号 2&#xff09;选取一定比例的身份号作为测试集 3&#xff09;身份号的选取&#xff1a; 3、利用scikit-learn&#xff1a; 1) 随机生成&#xff1a; 2&#xff09;注&#xff1a;分类 3&a…

控制面板网站宁波网站建设服务

背景&#xff1a; 微软和谷歌母公司Alphabet最新公布的季度财报均显示&#xff0c;由于企业客户在人工智能服务上的投入增加&#xff0c;其云计算业务实现了显著的收入增长。尽管Meta在将人工智能技术转化为收益方面稍显滞后&#xff0c;但它表示&#xff0c;其相关努力对提高…

中山做网站专业的公司如何做网站竞品分析

2020年全国研究生数学建模大赛开始啦&#xff01;各学院&#xff1a; 为在大学生中倡导学习统计、应用统计的良好氛围&#xff0c;适应大数据时代的高校统计和数据科学人才的培养要求&#xff0c;提高研究生的数据挖掘、数据分析、运用计算机处理数据的能力&#xff0c;加强创新…

建设网站的企业费用东莞网络公司哪家好

背景在使用富士施乐的一体机中(其他厂商的一体机 也类似)&#xff0c;很多人的网络环境是动态IP的&#xff0c;即打印的IP地址是不固定的&#xff0c;随着每次开机或关机会变化&#xff0c;从而经常有人反应打印机不能打印或者扫描了。。总体思路1. 检查当前的IP设置2. 把相应的…

程序员做的简单的网站企业做网站和宣传册的作用

在视频制作过程中&#xff0c;为视频添加引人注目的封面是吸引观众的关键。而当我们需要批量处理多个视频时&#xff0c;如何快速、准确地置入封面就显得尤为重要。本文将为您揭示这一高效技巧&#xff0c;让您在一分钟内学会批量置入视频封面&#xff0c;提升视频的吸引力与观…

.NET驾驭Word之力:结构化文档元素操作

在前几篇文章中,我们学习了Word对象模型的基础知识、文本操作与格式设置等内容。掌握了这些基础知识后,我们现在可以进一步深入到文档的结构化元素操作,包括段落与节的管理、表格的创建与操作以及图片的插入等。本文…

行稳、致远 | 技术驱动下的思考感悟

行稳: 做好当下,结果第一 读书和加入京东以来的这十几年,我感触最深的一个点就是要做好当下。我个人是一个思维比较跳脱,想法算是比较多的人。总是喜欢瞎折腾,喜欢想东想西。有时候有点 “这山望见那山高” 的意思…

在控制台执行这段代码可以列出所有::selection规则

// 在控制台执行这段代码可以列出所有::selection规则 Array.from(document.styleSheets).forEach(sheet => { try { Array.from(sheet.cssRules).forEach(rule => { if(rule.selectorText && rule.sele…

JDK从8升级到21的问题集

一、背景与挑战 1.升级动因 ◦Oracle长期支持策略 ◦现代特性需求:协程、模式匹配、ZGC等 ◦安全性与性能的需求 ◦AI新技术引入的版本要求 2.项目情况 ◦100+项目并行升级的协同作战 ◦多技术栈并存 ◦持续集成体系的…

网站建设公司调查报告wordpress多国语言版本

首先&#xff0c;Kafka无法保证消息的全局有序性&#xff0c;这是因为Kafka的设计中允许多个生产者并行地向同一个主题写入消息。而且&#xff0c;一个主题可能会被划分为多个分区&#xff0c;每个分区都可以在独立的生产者和消费者之间进行并行处理。因此&#xff0c;生产者将…

wordpress游客变用户品牌网站和优化网站

各位小伙伴们大家好&#xff0c;欢迎来到这个小扎扎的ElasticSearch专栏&#xff0c;本篇博客由B战尚硅谷的ElasticSearch视频总结而来&#xff0c;鉴于 看到就是学到、学到就是赚到 精神&#xff0c;这波依然是血赚 ┗|&#xff40;O′|┛ &#x1f306; 内容速览 1 es数据格…

网站色彩搭配方案泰安市高新区建设局网站

前言 当谈到异步编程时&#xff0c;C#中的async/await是一个强大且方便的工具。它使得编写并发和异步操作变得更加简单和可读&#xff0c;同时提供良好的可维护性。本文将详细解释async/await的使用&#xff0c;以及如何在C#中有效地利用它来实现异步操作。 目录 前言1. async…

先做网站装修还是先买虚拟主机wordpress china 中文

任务7:采集这5页中胜点列的数据,找出胜点最高的召唤师,将召唤师姓名填入答案中 此题采集的是胜点列表的数据如下 通过控制台审查元素查看,可以看到是乱码,记得几年前的快手,小红书,抖音也采用了此类反爬措施,html页面显示的是乱码,浏览器能正常显示数据,大概率就是…

科技公司网站案例做 在线观看免费网站

引言 在数据结构和算法的世界里&#xff0c;平衡二叉搜索树&#xff08;Balanced Binary Search Tree, BST&#xff09;是一种非常重要的数据结构。AVL树&#xff08;Adelson-Velsky和Landis发明的树&#xff09;就是平衡二叉搜索树的一种&#xff0c;它通过自平衡来维护其性质…

网站建设是用自己的服务器重庆室内设计

第1周&#xff1a;SQL入门 学习SQL语句的书写语法和规则从零学会SQL&#xff1a;入门​www.zhihu.com 第2周&#xff1a;查询基础 Select查询语句是SQL中最基础也是最重要的语句&#xff0c;这周我们就来利用Select来对表中的数据进行查询。从零学会SQL&#xff1a;简单查询​w…