from PyQt5 import *
from PyQt5.QtWidgets import *
import sys
class MyQComboCheckBox(QComboBox):
def __init__(self, items: list):
super(MyQComboCheckBox, self).__init__()
self.items = ["Select All"] + items
self.box_list = []
self.text = QLineEdit()
self.state = 0
q = QListWidget()
for i in range(len(self.items)):
self.box_list.append(QCheckBox())
self.box_list[i].setText(self.items[i])
item = QListWidgetItem(q)
q.setItemWidget(item, self.box_list[i])
if i == 0:
self.box_list[i].stateChanged.connect(self.all_selected)
else:
self.box_list[i].stateChanged.connect(self.show_selected)
self.setStyleSheet("QComboBox { combobox-popup: 0;\n"
"border: 1px solid rgb(218,218,218);\n"
"width:48px;\n"
"height:24px;\n"
"line-height:24px; }\n")
self.text.setReadOnly(True)
self.setLineEdit(self.text)
self.setModel(q.model())
self.setView(q)
self.setMaxVisibleItems(50) # 重点:避免滑条的出现引起滑条偷吃标签的问题
def all_selected(self):
if self.state == 0:
self.state = 1
for i in range(1, len(self.items)):
self.box_list[i].setChecked(True)
else:
self.state = 0
for i in range(1, len(self.items)):
self.box_list[i].setChecked(False)
self.show_selected()
def get_selected(self) -> list:
ret = []
for i in range(1, len(self.items)):
if self.box_list[i].isChecked():
ret.append(self.box_list[i].text())
return ret
def show_selected(self):
self.text.clear()
ret = '; '.join(self.get_selected())
self.text.setText(ret)
class UiMainWindow(QWidget):
def __init__(self):
super(UiMainWindow, self).__init__()
self.setWindowTitle('Combobox Multi-Selection')
self.resize(600, 400)
items=["Python", "Java", "Go", "C++", "JavaScript", "PHP"]
combo = MyQComboCheckBox(items)
combo2 = MyQComboCheckBox(items)
layout = QVBoxLayout()
layout.addWidget(combo)
layout.addWidget(combo2)
self.setLayout(layout)
if __name__ == "__main__":
app = QApplication(sys.argv)
ui = UiMainWindow()
ui.show()
sys.exit(app.exec_())