From 23111bbc8f17c3d6feaf782a9239b548d26068cf Mon Sep 17 00:00:00 2001 From: pzkn3atj5 Date: Fri, 26 May 2023 15:54:44 +0800 Subject: [PATCH] ADD file via upload --- ComboCheckBox.py | 125 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 ComboCheckBox.py diff --git a/ComboCheckBox.py b/ComboCheckBox.py new file mode 100644 index 0000000..1b5142a --- /dev/null +++ b/ComboCheckBox.py @@ -0,0 +1,125 @@ + +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)