Skip to content Skip to sidebar Skip to footer

Dynamic QComboBox Fill Dependent On User Input PyQt5

I created QTableWidget and in first two columns inserted comboboxes. The first column contains unique records (first elements from list of lists). My aim is to make these combo box

Solution 1:

The first task that must be done is to create a structure of data that allows to handle the data of simple form, in this case a dictionary is used that contain lists:

self.d = {" ": []}

for item in list1:
    combo1 = item[0]
    combo2 = item[2]
    if combo2 not in self.d[" "]:
        self.d[" "].append(combo2)

    if combo1 in self.d.keys():
        if combo2 not in self.d[combo1]:
            self.d[combo1].append(combo2)
    else:
        self.d[combo1] = []

Output:

{ 
   ' '         : ['PP', 'BR', 'KL'], 
   'Butterfly' : ['PP', 'BR'], 
   'Backpack'  : ['BR'], 
   'Toy'       : ['KL'] 
}

Then connect the currentTextChanged signals of the QComboBox, but you must also pass the other associated QComboBox for that the lambda function is used. with the blockSignals() method we block that a loop is generated between the signals.

class Window(QMainWindow):
    [...]
    def Table_of_widgets(self):
        [...]

        list1 = [...]


        self.d = {" ": [" "]}
        self.d_inverse = {" ": [" "]}

        def createData(key1, key2, data):
            if key2 not in data[" "]:
                data[" "].append(key2)
            if key1 in data.keys():
                if key2 not in data[key1]:
                    data[key1].append(key2)
            else:
                data[key1] = [" ", key2]
            return data

        for item in list1:
            item1 = item[0]
            item2 = item[2]
            self.d = createData(item1, item2, self.d)
            self.d_inverse = createData(item2, item1, self.d_inverse)

        for i in range(rowCount):
            comboA = QComboBox()
            comboB = QComboBox()
            comboA.addItems(self.d.keys())
            comboB.addItems(self.d[comboA.currentText()])
            self.table.setCellWidget(i, 0, comboA)
            self.table.setCellWidget(i, 1, comboB)
            comboA.currentTextChanged.connect(lambda text, row=i: self.onComboACurrentTextChanged(text, row))
            comboB.currentTextChanged.connect(lambda text, row=i: self.onComboBCurrentTextChanged(text, row))

    def updateCombox(self, combo1, combo2, item1, item2):
        text = combo1.currentText()
        combo1.blockSignals(True)
        combo2.blockSignals(True)
        combo1.clear()
        combo2.clear()

        combo2.addItems(item1[text])
        combo2.setCurrentIndex(1 if text != " " else 0)
        combo1.addItems(item2[combo2.currentText()])
        combo1.setCurrentText(text)

        combo1.blockSignals(False)
        combo2.blockSignals(False)

    def onComboACurrentTextChanged(self, text, row):
        comboA = self.table.cellWidget(row, 0)
        comboB = self.table.cellWidget(row, 1)
        self.updateCombox(comboA, comboB, self.d, self.d_inverse)

    def onComboBCurrentTextChanged(self, text, row):
        comboA = self.table.cellWidget(row, 0)
        comboB = self.table.cellWidget(row, 1)
        self.updateCombox(comboB, comboA, self.d_inverse, self.d)

Post a Comment for "Dynamic QComboBox Fill Dependent On User Input PyQt5"