效果:
源码:
from PySide6.QtWidgets import QComboBox, QListWidget, QCheckBox, QListWidgetItem, QLineEdit, QApplication, QHBoxLayout, \
QWidget
from PySide6.QtGui import Qt
from PySide6.QtCore import Signal
# 自定义控件-点击按钮下拉CheckBox列表
class XCombobox(QComboBox):
# 有item被选择时,发出信号
itemChecked = Signal(list)
# 保存QCheckBox控件
_checks = []
def __init__(self, parent) -> None:
super().__init__(parent)
# 通过setView()设置下拉列表控件,通过setLineEdit替换原有的文本显示控件,并设置为只读模式。预设"全选"选项。
listwgt = QListWidget(self)
self.setView(listwgt)
self.setModel(listwgt.model())
lineEdit = QLineEdit(self)
lineEdit.setReadOnly(True)
self.setLineEdit(lineEdit)
# 预设'全选'
self.add_item('全选')
def add_item(self, text: str):
# 在这里给每个CheckBox都绑定了信号,目的是每次Check都能作出响应。
check = QCheckBox(text, self.view())
check.stateChanged.connect(self.on_state_changed)
self._checks.append(check)
item = QListWidgetItem(self.view())
# 设置item不可选中(只可以被Check)
item.setFlags(item.flags() & Qt.IntersectsItemShape)
self.view().addItem(item)
self.view().setItemWidget(item, check)
def add_items(self, texts: list):
for text in texts:
self.add_item(text)
def clear(self):
self.view().clear()
def get_selected(self):
sel_data = []
for chk in self._checks:
if self._checks[0] == chk:
continue
if chk.checkState() == Qt.Checked:
sel_data.append(chk.text())
return sel_data
def set_all_state(self, state):
for chk in self._checks:
chk.blockSignals(True)
chk.setCheckState(Qt.CheckState(state))
chk.blockSignals(False)
def on_state_changed(self, state):
if self.sender() == self._checks[0]:
self.set_all_state(state)
sel_data = self.get_selected()
self.itemChecked.emit(sel_data)
self.lineEdit().setText(';'.join(sel_data))
def printa(data: list):
print(data)
if __name__ == '__main__':
app = QApplication()
wind = QWidget()
wind.resize(500, 500)
cmbox = XCombobox(wind)
cmbox.add_items(['AAA', 'BBB', 'CCC', 'DDD','AAA', 'BBB', 'CCC', 'DDD','AAA', 'BBB', 'CCC', 'DDD','AAA', 'BBB', 'CCC', 'DDD','AAA', 'BBB', 'CCC', 'DDD','AAA', 'BBB', 'CCC', 'DDD','AAA', 'BBB', 'CCC', 'DDD','AAA', 'BBB', 'CCC', '11DDD'])
# cmbox.itemChecked.connect(printa)
hyout = QHBoxLayout(wind)
hyout.addWidget(cmbox)
wind.setLayout(hyout)
wind.show()
app.exec()