Reputation: 19
I would like to filter the items in a PyQt5 QCombobox when checking certain checkboxes.
Example:
samplelist=["a1","a2","a3","b1","b2","b3"]
is the list of items of the QCombobox comboBox
and I have two checkboxes checkBoxa
and checkBoxb
. If
checkboxa
checked and checkboxb
unchecked: comboBox
has the items ["a1", "a2", "a3"]
checkboxa
unchecked and checkboxb
is checked: comboBox
has the items ["b1", "b2", "b3"]
checkboxa
unchecked and checkboxb
is unchecked: comboBox
is emptycheckboxa
checked and checkboxb
is checked: comboBox
has samplelist
Does anyone have an idea how I can connect checkboxa
and checkbox
to the comboBox
to achieve the described result?
Minimal example (checkboxes are not connected to the combobox)
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class ExampleWindow(QDialog):
def __init__(self,parent=None):
super(ExampleWindow,self).__init__(parent)
mainLayout=QtWidgets.QGridLayout()
samplelist=["a1","a2","a3","b1","b2","b3"]
# Create combobox and add items.
self.comboBox = QComboBox()
self.comboBox.addItems(samplelist)
#Create checkboxes
self.checkBoxa = QCheckBox("Select a")
self.checkBoxb = QCheckBox("Select b")
mainLayout.addWidget(self.comboBox,1,0,1,2)
mainLayout.addWidget(self.checkBoxa,0,0,1,1)
mainLayout.addWidget(self.checkBoxb,0,1,1,1)
self.setLayout(mainLayout)
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = ExampleWindow()
mainWin.show()
sys.exit( app.exec_() )
Upvotes: 1
Views: 212
Reputation: 243907
Since your question is not explicit, I will assume that each QCheckBox is associated with a letter and you want to show only the items that start with a letter associated with the checked QCheckBoxs. If so then it is better to create a model based on the items and filter them using a QSortFilterProxyModel.
class FilterProxyModel(QSortFilterProxyModel):
def __init__(self, parent=None):
super().__init__(parent)
self._letters = list()
@property
def letters(self):
return self._letters
@letters.setter
def letters(self, letters):
self._letters = letters.copy()
self.invalidateFilter()
def filterAcceptsRow(self, source_row, source_parent):
index = self.sourceModel().index(source_row, 0, source_parent)
data = index.data()
return any(data.startswith(letter) for letter in self.letters)
class ExampleWindow(QDialog):
def __init__(self, parent=None):
super(ExampleWindow, self).__init__(parent)
mainLayout = QGridLayout(self)
letters = ("a", "b", "c", "d")
samplelist = [f"{letter}{i}" for i in range(1, 5) for letter in letters]
self.model = QStandardItemModel()
for e in samplelist:
item = QStandardItem(e)
self.model.appendRow(item)
self.proxy_model = FilterProxyModel()
self.proxy_model.setSourceModel(self.model)
self.comboBox = QComboBox()
self.comboBox.setModel(self.proxy_model)
self.checkboxs = []
for i, letter in enumerate(letters):
checkbox = QCheckBox(f"Select {letter}")
checkbox.setProperty("letter", letter)
checkbox.toggled.connect(self.handle_toggled)
mainLayout.addWidget(checkbox, 0, i)
self.checkboxs.append(checkbox)
mainLayout.addWidget(self.comboBox, 1, 0, 1, len(letters))
self.handle_toggled()
def handle_toggled(self):
letters = []
for checkbox in self.checkboxs:
if checkbox.isChecked():
letters.append(checkbox.property("letter"))
self.proxy_model.letters = letters
Upvotes: 1