Search code examples
pythonqtlambdasignalsfunctools

Yet another solution needed for binding button signals to slots in Qt


I'm trying to develop a Slicer module in Python, using qt. I have a list of buttons (QPushButton) and I want each of their "clicked" signals to be bound to the same method but passing different arguments (that is just to know what button was pressed).

What I'm looking for is something like this:

def createButtons(self):
  for object in self.myList:
    button = qt.QPushButton(object.name)
    button.clicked.connect(self.myMethod(object.name)) # I know this is not valid

def myMethod(self, name):
  print name, 'was pressed.'

I already used all the three ways suggested here and here, but I have different problems:

  • The QSignalMapper solution is a mess because I can't use PyQt/PySide.

  • The lambda solution makes my code print always the text of the last button, no matter which one is pressed. I wrote something like:

    button.clicked.connect(lambda : self.myMethod(object.name))
    
  • The partial solution was implemented as:

    button.clicked.connect(functools.partial(self.myMethod, object.name))
    

    But I got the following error:

    TypeError: myMethod() takes exactly 2 arguments (3 given)
    

Right now I'm using a horrible list of different written methods, so my ugly solution, which works, is:

button.clicked.connect(self.myButtonMethods[self.myList.index(object)])

I hope my question hasn't been asked before and that you can help me.

Thanks!


Solution

  • According to this page, pyQT after 4.5 introduced a new API

    try this:

    QtCore.QObject.connect(button, QtCore.SIGNAL('clicked()'), functools.partial(self.myMethod, object.name) )