You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

126 lines
4.4 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

from PyQt5.QtWidgets import QWidget, QComboBox, QLineEdit, QListView
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QMouseEvent
from PyQt5.Qt import Qt
global classIds
classIds = ''
# 全选与单选的绑定(没有这个会导致勾选数据错乱)
def show_text(function):
def wrapped(self, *args, **kwargs):
global classIds
if self.vars["showTextLock"]:
self.vars["showTextLock"] = False
result = function(self, *args, **kwargs)
items = self.get_selected()
l = len(items)
l_ = self.vars["listViewModel"].rowCount() - 1
self.vars["listViewModel"].item(0).setCheckState(
Qt.Checked if l == l_ else Qt.Unchecked if l == 0 else Qt.PartiallyChecked)
self.vars["lineEdit"].setText(
"(全选)" if l == l_ else "(无选择)" if l == 0 else ";".join((item.text() for item in items)))
self.vars["showTextLock"] = True
classIds = "" if l == 0 else ",".join((item.text().split('.')[0] for item in items))
else:
result = function(self, *args, **kwargs)
return result
return wrapped
# 选项的渲染和选择后的显示
class QComboCheckBox(QComboBox):
class MyListView(QListView):
def __init__(self, parent: QWidget = None, vars=None):
super().__init__(parent)
self.vars = vars
def mousePressEvent(self, event: QMouseEvent):
self.vars["lock"] = False
super().mousePressEvent(event)
def mouseDoubleClickEvent(self, event: QMouseEvent):
self.vars["lock"] = False
super().mouseDoubleClickEvent(event)
def __init__(self, parent: QWidget = None):
super().__init__(parent)
self.vars = dict()
self.vars["lock"] = True
self.vars["showTextLock"] = True
# 装饰器锁避免批量操作时重复改变lineEdit的显示
self.vars["lineEdit"] = QLineEdit(self)
self.vars["lineEdit"].setReadOnly(True)
self.vars["listView"] = self.MyListView(self, self.vars)
self.vars["listViewModel"] = QStandardItemModel(self)
self.setModel(self.vars["listViewModel"])
self.setView(self.vars["listView"])
self.setLineEdit(self.vars["lineEdit"])
self.activated.connect(self.__show_selected)
self.add_item("(全选)")
@show_text
def add_item(self, text: "str", flag=False):
# 根据文本添加子项
item = QStandardItem()
item.setText(text)
item.setCheckable(True)
if flag:
item.setCheckState(Qt.Checked)
self.vars["listViewModel"].appendRow(item)
# 根据文本查找子项
def find_text(self, text: "str"):
tempList = self.vars["listViewModel"].findItems(text)
tempList.pop(0) if tempList and tempList[0].row() == 0 else tempList
return tempList
# 获取班级ids
def get_class_text(self):
return classIds
@show_text # 全选
def select_all(self):
for row in range(0, self.vars["listViewModel"].rowCount()):
self.vars["listViewModel"].item(row).setCheckState(Qt.Checked)
@show_text # 全不选
def select_clear(self):
for row in range(0, self.vars["listViewModel"].rowCount()):
self.vars["listViewModel"].item(row).setCheckState(Qt.Unchecked)
# 获取当前选择的子项
def get_selected(self):
items = list()
for row in range(1, self.vars["listViewModel"].rowCount()):
item = self.vars["listViewModel"].item(row)
if item.checkState() == Qt.Checked:
items.append(item)
return items
@show_text # 显示选中的选项
def __show_selected(self, index):
# 未被选中
if not self.vars["lock"]:
# 选中全选
if index == 0:
if self.vars["listViewModel"].item(0).checkState() == Qt.Checked:
self.select_clear()
else:
self.select_all()
# 选中其他
else:
self.__select_reverse(index)
self.vars["lock"] = True
# 选中一个选项
def __select_reverse(self, row: "int"):
item = self.vars["listViewModel"].item(row)
item.setCheckState(Qt.Unchecked if item.checkState() == Qt.Checked else Qt.Checked)