0

I have a table full of comboBoxes created by the push of a button.My question is how do you find out which comboBox changed ? If it was a fixed comboBox, I would use the following:

QtCore.QObject.connect(self.comboBox, QtCore.SIGNAL(_fromUtf8("currentIndexChanged(int)")), self.dosomething)

I have added the example code below to make it more clear:

from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    _fromUtf8 = lambda s: s

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName(_fromUtf8("Dialog"))
        Dialog.resize(332, 122)
        Dialog.setMinimumSize(QtCore.QSize(332, 122))
        Dialog.setMaximumSize(QtCore.QSize(332, 122))
        self.tableWidget = QtGui.QTableWidget(Dialog)
        self.tableWidget.setGeometry(QtCore.QRect(10, 10, 256, 101))
        self.tableWidget.setObjectName(_fromUtf8("tableWidget"))
        self.tableWidget.setColumnCount(2)   
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        self.tableWidget.setRowCount(0)
        self.layoutWidget_6 = QtGui.QWidget(Dialog)
        self.layoutWidget_6.setGeometry(QtCore.QRect(280, 30, 40, 54))
        self.layoutWidget_6.setObjectName(_fromUtf8("layoutWidget_6"))
        self.verticalLayout_2 = QtGui.QVBoxLayout(self.layoutWidget_6)
        self.verticalLayout_2.setMargin(0)
        self.verticalLayout_2.setObjectName(_fromUtf8("verticalLayout_2"))
        self.pushButton_2 = QtGui.QPushButton(self.layoutWidget_6)
        self.pushButton_2.setAutoDefault(False)
        self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
        self.verticalLayout_2.addWidget(self.pushButton_2)
        self.pushButton = QtGui.QPushButton(self.layoutWidget_6)
        self.pushButton.setAutoDefault(False)
        self.pushButton.setObjectName(_fromUtf8("pushButton"))
        self.verticalLayout_2.addWidget(self.pushButton)

        QtCore.QObject.connect(self.pushButton_2, QtCore.SIGNAL(_fromUtf8("clicked()")), self.add)

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_2.setText(QtGui.QApplication.translate("Dialog", "+", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton.setText(QtGui.QApplication.translate("Dialog", "-", None, QtGui.QApplication.UnicodeUTF8))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(QtGui.QApplication.translate("Dialog", "New Column", None, QtGui.QApplication.UnicodeUTF8))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(QtGui.QApplication.translate("Dialog", "New Column", None, QtGui.QApplication.UnicodeUTF8))

    def change(self):
        '''Depending on the comboBox whose index has changed,
         find the row and insert the right options in the comboBox
          in the next column'''

        #Find the row
        ins = self.tableWidget.focusWidget()
        selected_row = self.tableWidget.indexAt(ins.pos()).row()
        choice = self.tableWidget.cellWidget(0, selected_row).currentText()

        #Select the appropriate options
        if choice == 'B':
            choices_list = ['4', '5', '6']
        if choice == 'A':
            choices_list = ['1', '2', '3']

        #Set ComboBox in the next column
        comboBox = QtGui.QComboBox(self.tableWidget)
        font = QtGui.QFont()
        font.setPointSize(10)
        comboBox.setFont(font)

        for combo_ind, i in enumerate(choices_list):
            comboBox.addItem(_fromUtf8(""))
            comboBox.setItemText(combo_ind, QtGui.QApplication.translate("Dialog", i, None, QtGui.QApplication.UnicodeUTF8))

    def add(self):
        index = self.tableWidget.rowCount()
        self.tableWidget.insertRow(index)

        comboBox = QtGui.QComboBox(self.tableWidget)
        font = QtGui.QFont()
        font.setPointSize(10)
        comboBox.setFont(font)

        for combo_ind, i in enumerate(["A", "B"]):
            comboBox.addItem(_fromUtf8(""))
            comboBox.setItemText(combo_ind, QtGui.QApplication.translate("Dialog", i, None, QtGui.QApplication.UnicodeUTF8))     
        self.tableWidget.setCellWidget(index, 0, comboBox)

        comboBox = QtGui.QComboBox(self.tableWidget)
        font = QtGui.QFont()
        font.setPointSize(10)
        comboBox.setFont(font)

        #[1,2,3] is for A
        #[4,5,6] is for B
        for combo_ind, i in enumerate(['1', '2', '3']):
            comboBox.addItem(_fromUtf8(""))
            comboBox.setItemText(combo_ind, QtGui.QApplication.translate("Dialog", i, None, QtGui.QApplication.UnicodeUTF8))
        self.tableWidget.setCellWidget(index, 1, comboBox) 

app = QApplication(sys.argv)
app.setApplicationName('MyWindow')
window = QDialog()
ui = Ui_Dialog()
ui.setupUi(window)
window.show()
sys.exit(app.exec_())
IordanouGiannis
  • 4,149
  • 16
  • 65
  • 99
  • In your `add` method you create a combo box, but I don't see that you ever connect any of its signals to a slot. It looks like you're almost there, just add the `QtCore.QObject.connect` we've already discussed, add a method (the `dosomething` up above) to handle the events, use the lambda trick I show in my answer below, and I think you've got it. – DMH Jul 15 '13 at 15:48

2 Answers2

1

One thing you might try is using a lambda, as in this similar question.

In your case it might look something like the following:

QtCore.QObject.connect(self.comboBox, QtCore.SIGNAL("currentIndexChanged(int)"), lambda index: self.dosomething(combo_id, index))

And you correspondingly change your self.dosomething method to take an extra parameter (say, an ID of some kind). This would allow you to pass on some identifying information about the event, i.e. which combo box it happened to, and as a bonus you get to re-use one method for all your components even as new ones are added.

Also note: In your case the signal is passing a value (int) to the slot. You need that information too, so you capture it as an argument for the lambda (above I have called it index ) and pass it to your slot method along with the identifying information ( combo_id ) about which combo box the signal is for.

If your signal doesn't send any parameters to the slot, such as for a button click, you need not use the lambda argument, like so:

QtCore.QObject.connect(self.button, QtCore.SIGNAL("clicked()"), lambda: self.dosomething(button_id))

Hope this helps.

Community
  • 1
  • 1
DMH
  • 3,875
  • 2
  • 26
  • 25
  • So, how do you get the combo_id and the index? – IordanouGiannis Jul 15 '13 at 09:55
  • The `index` is the new index set by the user in your combo box (the int being passed in the signal), which is set for you. The combo_id is something you have to set somehow when you dynamically create your combo box... You can do it any way you want, I just used this as an example. You can do this at the same time you create the combo box and connect its signals to a slot, like you did above. Make sense? – DMH Jul 15 '13 at 12:29
0

You need to re-implement widget that you want to create dynamically. Basically this code is answer to this question, too.

Community
  • 1
  • 1
Aleksandar
  • 3,541
  • 4
  • 34
  • 57