Question

My objective is to give the user QComboBoxes depending on the number he/she selected on the QSpinbox.

So, it will be something like this:

User will select a number on QSpinbox,after that, by using the signal valueChanged(int) i want to invoke another function that will create QComboBoxes for user to enter the data.

As soon as user change to another value. It will automatically increase / decrease the QComboBox numbers depending on the QSpinbox value.

So i came up with something like this:

def myfunction(x):
    labellist = []
    combolist = []
    layoutlist = []
    layout = QtGui.QVBoxLayout()
    for i in range(x):
        labellist.append(QtGui.QLabel('this is label'+str(i))
        combolist.append(QtGui.QComboBox())
        layoutlist.append(QtGui.QHBoxLayout())
        layoutlist[i].addWidget(labellist[i])
        layoutlist[i].addWidget(combolist[i])
        layout.addLayout(layoutlist[i])


self.connect(number,QtCore.SIGNAL("valueChanged(int)"),myfunction)

Even though it create ComboBoxes depending on the number user selected on spin box, when user increase the number (eg. 3 to 4), it doesn't remove the old 3comboBoxes, instead it become 7 comboboxes all together.

How do i fix this? Or Is there a better way to achieve the similar result?

Was it helpful?

Solution

You could delete and recreate all the comboboxes everytime your spinbox value changes. It may not be the most efficient, but it's quite simple.

Just have a list with references to the labels/comboxes as an attribute. In your slot, call deleteLater() on each item, then delete the reference by setting your list to []. Finally, recreate the items, add them to your layout and repopulate your list.

Also, you should have a look at New Style Signals and Slots. They are nicer than the ugly C++ style connect.

class DynamicComboBoxes(QtGui.QWidget):
    def __init__(self, parent=None):
        super(DynamicComboBoxes, self).__init__(parent)
        vbox = QtGui.QVBoxLayout(self)
        spinbox = QtGui.QSpinBox(self)
        spinbox.setRange(0,10)
        spinbox.valueChanged.connect(self.onChangeValue)
        vbox.addWidget(spinbox)
        self.grid = QtGui.QGridLayout()
        self.itemlist = []
        vbox.addLayout(self.grid)
        vbox.addStretch(1)


    def onChangeValue(self, val):
        for label, combobox in self.itemlist:
            label.deleteLater()
            combobox.deleteLater()
        self.itemlist = []
        for i in range(val):
            label = QtGui.QLabel('This is Label {}'.format(i))
            combobox = QtGui.QComboBox()
            self.grid.addWidget(label, i, 0)
            self.grid.addWidget(combobox, i, 1)
            self.itemlist.append([label, combobox])
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top