前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >在 PyQt5 中构建「省-市-县」级联选择器

在 PyQt5 中构建「省-市-县」级联选择器

作者头像
州的先生
发布2021-12-01 17:49:53
2.3K0
发布2021-12-01 17:49:53
举报
文章被收录于专栏:州的先生州的先生

一、Web 网页中的级联选择器

在各类网页中,我们经常可以看到级联选择器。

比如在购物平台填写收获地址的时候,进行省市县的选择;

又比如在一些商品分类中的商品大类、商品子类的选择:

可以说,对于一个正常的Web框架而言,级联选择器都是必不可少的组件。

二、级联选择器原理

其实普通的级联选择器其构成并不复杂。

无非是选择一级的时候,唤起二级的渲染和显示,选择二级的时候,唤起三级的渲染和显示;

至于各级是用列表还是用下拉框,都是其次的。

下面,我们就使用 PyQt5 构建一个省市县的级联选择器。

最终的效果如下所示:

三、构建一个桌面应用的级联选择器

准备数据

要实现省市县的级联选择,省市县的数据必不可少,在这里,我们使用的是一个 JSON 格式嵌套的省市县数据,如下图所示:

数据来源于:https://www.cnblogs.com/bihuijia/p/15077207.html

大家可以自行复制。

最终以data.json文件的形式提供给代码读取。

代码开发

首先,引入所需的模块:

代码语言:javascript
复制
from PyQt5 import QtWidgets,QtCore
from loguru import logger
import sys
import json

接着,编写其基础界面。

通过继承QtWidgets.QWidget,定义一个Widget:

代码语言:javascript
复制
class Widget(QtWidgets.QWidget):
    def __init__(self):
        super(Widget, self).__init__()
        self.setWindowTitle("PyQt5 省市县级联选择器 - 州的先生")
        self.init_data() # 初始化数据
        self.init_ui() # 初始化UI

Widget初始化的时候,我们调用了两个方法,分别用于初始化数据和初始化UI界面。

初始化数据,通过读取data.json文件进行 json 解析并赋值:

代码语言:javascript
复制
    # 初始化数据
    def init_data(self):
        # 读取json数据
        with open("./data.json", 'r', encoding='utf-8') as data:
            self.data_json = json.loads(data.read(), encoding='utf-8')
            print(self.data_json)

我们的级联选择器通过三个下拉选择器QComboBox()来实现,然后三个下拉选择器用一个网格布局QGridLayout()进行水平排列。

代码语言:javascript
复制
    # 初始化UI
    def init_ui(self):
        # 省选择器
        self.province = QtWidgets.QComboBox()
        self.province.addItem("--请选择省")
        self.province.currentTextChanged.connect(self.slot_province_click)
        for data in self.data_json:
            self.province.addItem(data['Name'])
        # 市选择器
        self.city = QtWidgets.QComboBox()
        self.city.addItem("--请选择市")
        self.city.currentTextChanged.connect(self.slot_city_click)
        # 县选择器
        self.county = QtWidgets.QComboBox()
        self.county.addItem("--请选择县")
        self.layout = QtWidgets.QGridLayout()
        self.setLayout(self.layout)
        self.layout.addWidget(self.province, 0, 0, 1, 1)
        self.layout.addWidget(self.city, 0, 1, 1, 1)
        self.layout.addWidget(self.county, 0, 2, 1, 1)

在这里,我们通过QComboBox()currentTextChanged信号来捕获下拉框某个选项被选择,分别连接到了两个方法:

代码语言:javascript
复制
    # 省选择器点击响应
    def slot_province_click(self):
        try:
            current_province = self.province.currentText()
            if current_province.startswith('--') is False:
                for data in self.data_json:
                    if data['Name'] == current_province:
                        self.city.clear()
                        self.current_city_data = data['Cities']
                        for c in data['Cities']:
                            self.city.addItem(c['Name'])
            else:
                self.city.clear()
                self.county.clear()
        except:
            logger.exception("加载市异常")
    # 市选择器点击响应
    def slot_city_click(self):
        try:
            current_city = self.city.currentText()
            if current_city.startswith('--') is False:
                for data in self.current_city_data:
                    if data['Name'] == current_city:
                        self.county.clear()
                        for c in data['Districts']:
                            self.county.addItem(c['Name'])
        except:
            logger.error("加载县区异常")

最后,完整代码如下所示:

代码语言:javascript
复制
# coding:utf-8
from PyQt5 import QtWidgets,QtCore
from loguru import logger
import sys
import json
class Widget(QtWidgets.QWidget):
    def __init__(self):
        super(Widget, self).__init__()
        self.setWindowTitle("PyQt5 省市县级联选择器 - 州的先生")
        self.init_data() # 初始化数据
        self.init_ui() # 初始化UI
    # 初始化数据
    def init_data(self):
        # 读取json数据
        with open("./data.json", 'r', encoding='utf-8') as data:
            self.data_json = json.loads(data.read(), encoding='utf-8')
            print(self.data_json)
    # 初始化UI
    def init_ui(self):
        # 省选择器
        self.province = QtWidgets.QComboBox()
        self.province.addItem("--请选择省")
        self.province.currentTextChanged.connect(self.slot_province_click)
        for data in self.data_json:
            self.province.addItem(data['Name'])
        # 市选择器
        self.city = QtWidgets.QComboBox()
        self.city.addItem("--请选择市")
        self.city.currentTextChanged.connect(self.slot_city_click)
        # 县选择器
        self.county = QtWidgets.QComboBox()
        self.county.addItem("--请选择县")
        self.layout = QtWidgets.QGridLayout()
        self.setLayout(self.layout)
        self.layout.addWidget(self.province, 0, 0, 1, 1)
        self.layout.addWidget(self.city, 0, 1, 1, 1)
        self.layout.addWidget(self.county, 0, 2, 1, 1)
    # 省选择器点击响应
    def slot_province_click(self):
        try:
            current_province = self.province.currentText()
            if current_province.startswith('--') is False:
                for data in self.data_json:
                    if data['Name'] == current_province:
                        self.city.clear()
                        self.current_city_data = data['Cities']
                        for c in data['Cities']:
                            self.city.addItem(c['Name'])
            else:
                self.city.clear()
                self.county.clear()
        except:
            logger.exception("加载市异常")
    # 市选择器点击响应
    def slot_city_click(self):
        try:
            current_city = self.city.currentText()
            if current_city.startswith('--') is False:
                for data in self.current_city_data:
                    if data['Name'] == current_city:
                        self.county.clear()
                        for c in data['Districts']:
                            self.county.addItem(c['Name'])
        except:
            logger.error("加载县区异常")
def main():
    app = QtWidgets.QApplication(sys.argv)
    gui = Widget()
    gui.show()
    sys.exit(app.exec())
if __name__ == '__main__':
    main()

四、最后

通过短短的不到100行代码,我们就在 PyQt5 上实现了一个完成的省市县级联选择器。如上述所说,级联的核心在于根据所选动态响应和渲染子级数据,至于用什么控件来实现,倒是次要的。

所以基于此,大家可以尝试使用别的控件来实现一下级联选择器,或者对这个级联选择器进行美化。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-11-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 州的先生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、Web 网页中的级联选择器
  • 二、级联选择器原理
  • 三、构建一个桌面应用的级联选择器
    • 准备数据
      • 代码开发
      • 四、最后
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档