1

I have four different combos like this:

cmb_filtermode_1 = QtGui.QComboBox()
cmb_filtermode_1.addItem("High Pass")
cmb_filtermode_1.addItem("Low Pass")

I already know how to connect a signal that triggers when an option is selected

cmb_filtermode_1.activated.connect( combo_chosen )

But that only sends a integer value to the slot. I would like to know if there is possible to get the combo which triggered the signal to have a single slot for all them.

def combo_chosen( combo ):
    if combo == 0: #0 is the index of Low-Pass
        #Do something here with the selected value and the combo who triggered
    elif combo == 1: #is the index of High-pass 
        #Do something here with the selected value and the combo who triggered
Mr_LinDowsMac
  • 2,644
  • 9
  • 56
  • 75

3 Answers3

1

Yes, it is possible, use sender() method inside your slot. For example:

sender = self.sender()

Sender variable contains widget which emitted signal. Good example you can also find here.

I suppose that you wrote your slot as simple function, not as QObject's subclass method. sender() is a method of QObject, so you can use this approach only in class.

Your error for example:

def buttonClicked(self):

    sender = self.sender()
    sender.setText('2')

class Example(QMainWindow):

    def __init__(self):
        super(Example, self).__init__()

        self.initUI()

    def initUI(self):      

        btn1 = QtGui.QPushButton("Button 1", self)
        btn1.move(30, 50)

        btn2 = QtGui.QPushButton("Button 2", self)
        btn2.move(150, 50)

        btn1.clicked.connect( buttonClicked)            
        btn2.clicked.connect(buttonClicked)

        self.statusBar()

        self.setGeometry(300, 300, 290, 150)
        self.setWindowTitle('Event sender')
        self.show()


def main():

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

Correct approach:

class Example(QMainWindow):

    def __init__(self):
        super(Example, self).__init__()

        self.initUI()

    def initUI(self):      

        btn1 = QtWidgets.QPushButton("Button 1", self)
        btn1.move(30, 50)

        btn2 = QtWidgets.QPushButton("Button 2", self)
        btn2.move(150, 50)

        btn1.clicked.connect(self.buttonClicked)            
        btn2.clicked.connect(self.buttonClicked)

        self.statusBar()

        self.setGeometry(300, 300, 290, 150)
        self.setWindowTitle('Event sender')
        self.show()

    def buttonClicked(self):# now it is method

        sender = self.sender()
        sender.setText('2')

def main():

    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()
Jablonski
  • 18,083
  • 2
  • 46
  • 47
1

Don't bother yourself with the complicated things. You just need to use lambda expression to pass the combo to the slot.

cmb_filtermode_1 = QtGui.QComboBox()
cmb_filtermode_1.addItem("High Pass")
cmb_filtermode_1.addItem("Low Pass")
cmb_filtermode_1.activated.connect( lambda index: combo_chosen(cmb_filtermode_1) )

lambda creates an anonymous function, the combo's signal is connected to this function, which calls the actual slot inside it passing the combo object to the slot.

def combo_chosen(combo):
    # combo is QComboBox that sent the signal
    print combo.currentText() # prints the selected items text
qurban
  • 3,885
  • 24
  • 36
1

If you don't want to use self.sender() because you want to call a function rather than a method, then you can connect to a lambda expression which in turn calls your function, passing in a reference to the combobox.

For example

cmb_filtermode_1.activated.connect( lambda index, combobox=cmb_filtermode_1: combo_chosen(index, combobox) )
cmb_filtermode_2.activated.connect( lambda index, combobox=cmb_filtermode_2: combo_chosen(index, combobox) )

Now you just adjust the default argument for combobox for each one (see example above).

Modify your function accordingly:

def combo_chosen( index, combobox ):
    if index == 0: #0 is the index of Low-Pass
        #Do something here with the selected value and the combo who triggered
    elif index == 1: #is the index of High-pass 
        #Do something here with the selected value and the combo who triggered

Note: it is important that you keep the combobox=cmb_filtermode_x argument as shown (rather than directly passing it to the combo_chosen function) in case the variable is reused later to point to a different combobox. This SO answer covers why you need to do this (though note some of it uses the old signal/slot syntax so may be confusing).

Community
  • 1
  • 1
three_pineapples
  • 11,579
  • 5
  • 38
  • 75