Sending Arbitrary Arguments to a pyQt4 Slot
Okay, so you can't send extra arguments through a slot when you connect it in pyQt4. What I mean by that is if you are connecting to a button's clicked() signal it has zero arguments, so you don't get to send anything to your slot.
This was a really big annoyance, I wanted to send arbitrary arguments defined at connect time. So I looked, and I looked and eventually, I found this treasure. Awesome.
# this creates a class that allows currying of functions
class Curry:
#keep a reference to all curried instances·
#or they are immediately garbage collected
instances = []
def __init__(self, func, *args, **kwargs):
self.func = func
self.pending = args[:]
self.kwargs = kwargs.copy()
self.instances.append(self)
def __call__(self, *args, **kwargs):
kw = self.kwargs
kw.update(kwargs)
funcArgs = self.pending + args
#sometimes we want to limit the number of arguments that get passed,
#calling the constructor with the option __max_args__ = n will limit
#the function call args to the first n items
maxArgs = kw.get("__max_args__", -1)
if maxArgs != -1:
funcArgs = funcArgs[:maxArgs]
del kw["__max_args__"]
return self.func(*funcArgs, **kw)
And for usage...
button_1 = QtGui.QPushButton( "Button One" )
QtCore.QObject.connect( button_1, QtCore.SIGNAL( "clicked()" ), Curry( self.myslot, 'Hey, button one!' ) )
button_2 = QtGui.QPushButton( "Button One" )
QtCore.QObject.connect( button_2, QtCore.SIGNAL( "clicked()" ), Curry( self.myslot, 'Word, button two!' ) )
It's just what I needed, this is going into my stash of helpful hints.