This commit is contained in:
Irony 2018-12-23 13:07:31 +08:00
parent 7930a383a5
commit 6c687af34f
6 changed files with 9862 additions and 9849 deletions

View file

@ -1,113 +1,113 @@
#!/usr/bin/env python #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
''' '''
Created on 2018年1月27日 Created on 2018年1月27日
@author: Irony."[讽刺] @author: Irony."[讽刺]
@site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447 @site: http://alyl.vip, http://orzorz.vip, https://coding.net/u/892768447, https://github.com/892768447
@email: 892768447@qq.com @email: 892768447@qq.com
@file: ComboBox @file: ComboBox
@description: @description:
''' '''
import json import json
import sys import sys
from PyQt5.QtCore import Qt, QSortFilterProxyModel, QRegExp from PyQt5.QtCore import Qt, QSortFilterProxyModel, QRegExp
from PyQt5.QtGui import QStandardItemModel, QStandardItem from PyQt5.QtGui import QStandardItemModel, QStandardItem
from PyQt5.QtWidgets import QWidget, QApplication, QHBoxLayout, QComboBox,\ from PyQt5.QtWidgets import QWidget, QApplication, QHBoxLayout, QComboBox,\
QLabel, QSpacerItem, QSizePolicy QLabel, QSpacerItem, QSizePolicy
import chardet import chardet
__Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com" __Author__ = "By: Irony.\"[讽刺]\nQQ: 892768447\nEmail: 892768447@qq.com"
__Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]" __Copyright__ = "Copyright (c) 2018 Irony.\"[讽刺]"
__Version__ = "Version 1.0" __Version__ = "Version 1.0"
class SortFilterProxyModel(QSortFilterProxyModel): class SortFilterProxyModel(QSortFilterProxyModel):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(SortFilterProxyModel, self).__init__(*args, **kwargs) super(SortFilterProxyModel, self).__init__(*args, **kwargs)
self.setFilterRole(Qt.ToolTipRole) # 根据Qt.ToolTipRole角色过滤 self.setFilterRole(Qt.ToolTipRole) # 根据Qt.ToolTipRole角色过滤
self._model = QStandardItemModel(self) self._model = QStandardItemModel(self)
self.setSourceModel(self._model) self.setSourceModel(self._model)
def appendRow(self, item): def appendRow(self, item):
self._model.appendRow(item) self._model.appendRow(item)
def setFilter(self, _): def setFilter(self, _):
# 过滤 # 过滤
# self.sender()#发送者 # self.sender()#发送者
# 获取上一个下拉框中的item_code # 获取上一个下拉框中的item_code
item_code = self.sender().currentData(Qt.ToolTipRole) item_code = self.sender().currentData(Qt.ToolTipRole)
if not item_code: if not item_code:
return return
if item_code.endswith("0000"): # 过滤市 if item_code.endswith("0000"): # 过滤市
self.setFilterRegExp(QRegExp(item_code[:-4] + "\d\d00")) self.setFilterRegExp(QRegExp(item_code[:-4] + "\d\d00"))
elif item_code.endswith("00"): # 过滤市以下 elif item_code.endswith("00"): # 过滤市以下
self.setFilterRegExp(QRegExp(item_code[:-2] + "\d\d")) self.setFilterRegExp(QRegExp(item_code[:-2] + "\d\d"))
class Widget(QWidget): class CityLinkageWindow(QWidget):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(Widget, self).__init__(*args, **kwargs) super(CityLinkageWindow, self).__init__(*args, **kwargs)
layout = QHBoxLayout(self) layout = QHBoxLayout(self)
self.province_box = QComboBox(self, minimumWidth=200) # 市级以上 self.province_box = QComboBox(self, minimumWidth=200) # 市级以上
self.city_box = QComboBox(self, minimumWidth=200) # 市 self.city_box = QComboBox(self, minimumWidth=200) # 市
self.county_box = QComboBox(self, minimumWidth=200) # 市级以下 self.county_box = QComboBox(self, minimumWidth=200) # 市级以下
layout.addWidget(QLabel("省/直辖市/特别行政区", self)) layout.addWidget(QLabel("省/直辖市/特别行政区", self))
layout.addWidget(self.province_box) layout.addWidget(self.province_box)
layout.addItem(QSpacerItem( layout.addItem(QSpacerItem(
20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)) 20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum))
layout.addWidget(QLabel("", self)) layout.addWidget(QLabel("", self))
layout.addWidget(self.city_box) layout.addWidget(self.city_box)
layout.addItem(QSpacerItem( layout.addItem(QSpacerItem(
20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)) 20, 20, QSizePolicy.Expanding, QSizePolicy.Minimum))
layout.addWidget(QLabel("区/县", self)) layout.addWidget(QLabel("区/县", self))
layout.addWidget(self.county_box) layout.addWidget(self.county_box)
self.initModel() self.initModel()
self.initSignal() self.initSignal()
self.initData() self.initData()
def initSignal(self): def initSignal(self):
# 初始化信号槽 # 初始化信号槽
self.province_box.currentIndexChanged.connect( self.province_box.currentIndexChanged.connect(
self.city_model.setFilter) self.city_model.setFilter)
self.city_box.currentIndexChanged.connect(self.county_model.setFilter) self.city_box.currentIndexChanged.connect(self.county_model.setFilter)
def initModel(self): def initModel(self):
# 初始化模型 # 初始化模型
self.province_model = SortFilterProxyModel(self) self.province_model = SortFilterProxyModel(self)
self.city_model = SortFilterProxyModel(self) self.city_model = SortFilterProxyModel(self)
self.county_model = SortFilterProxyModel(self) self.county_model = SortFilterProxyModel(self)
# 设置模型 # 设置模型
self.province_box.setModel(self.province_model) self.province_box.setModel(self.province_model)
self.city_box.setModel(self.city_model) self.city_box.setModel(self.city_model)
self.county_box.setModel(self.county_model) self.county_box.setModel(self.county_model)
def initData(self): def initData(self):
# 初始化数据 # 初始化数据
datas = open("data.json", "rb").read() datas = open("Data/data.json", "rb").read()
encoding = chardet.detect(datas) or {} encoding = chardet.detect(datas) or {}
datas = datas.decode(encoding.get("encoding", "utf-8")) datas = datas.decode(encoding.get("encoding", "utf-8"))
datas = json.loads(datas) datas = json.loads(datas)
# 开始解析数据 # 开始解析数据
for data in datas: for data in datas:
item_code = data.get("item_code") # 编码 item_code = data.get("item_code") # 编码
item_name = data.get("item_name") # 名字 item_name = data.get("item_name") # 名字
item = QStandardItem(item_name) item = QStandardItem(item_name)
item.setData(item_code, Qt.ToolTipRole) item.setData(item_code, Qt.ToolTipRole)
if item_code.endswith("0000"): # 4个0结尾的是市级以上的 if item_code.endswith("0000"): # 4个0结尾的是市级以上的
self.province_model.appendRow(item) self.province_model.appendRow(item)
elif item_code.endswith("00"): # 2个0结尾的是市 elif item_code.endswith("00"): # 2个0结尾的是市
self.city_model.appendRow(item) self.city_model.appendRow(item)
else: # 市以下 else: # 市以下
self.county_model.appendRow(item) self.county_model.appendRow(item)
if __name__ == "__main__": if __name__ == "__main__":
app = QApplication(sys.argv) app = QApplication(sys.argv)
w = Widget() w = CityLinkageWindow()
w.show() w.show()
sys.exit(app.exec_()) sys.exit(app.exec_())

View file

@ -0,0 +1,12 @@
# QComboBox
## 1、Data Linkage
[View](CityLinkage.py) | [Run](CityLinkage.py)
Three level linkage, data file is data.json
1. use `QComboBox`,`setModel` and `QSortFilterProxyModel` to filter
2. the filter role is `Qt::ToolTipRole`
3. can use `QColumnView` maybe like this example
![CityLinkage](ScreenShot/CityLinkage.gif)

View file

@ -0,0 +1,12 @@
# QComboBox
## 1、下拉数据关联
[查看](CityLinkage.py) | [运行](CityLinkage.py)
一个省市区关联的三级联动数据源在data.json中
1. 主要用了`QComboBox`的`setModel`设置一个`QSortFilterProxyModel`过滤模型
2. 并根据唯一编码过滤,为了不影响内容显示,唯一编码的角色为`ToolTipRole`
3. 用`QColumnView`可以实现类似效果
![CityLinkage](ScreenShot/CityLinkage.gif)

View file

Before

Width:  |  Height:  |  Size: 100 KiB

After

Width:  |  Height:  |  Size: 100 KiB

View file

@ -1,11 +0,0 @@
# 下拉框
## [1、QComboBox下拉数据关联](下拉选择联动)
这里简单的做了一个省市区关联的三级联动数据源在data.json中
1. 主要用了`QComboBox`的`setModel`设置一个`QSortFilterProxyModel`过滤模型
2. 并根据唯一编码过滤,为了不影响内容显示,唯一编码的角色为`ToolTipRole`
3. 匆忙中写出来,可能有些不完善,或者该方式效率不是很高(后来发现可以用`QColumnView`实现)
![截图](下拉选择联动/ScreenShot/下拉选择联动.gif)