[PyKDE] Sending an argument to a function with a button click
Christian Bird
cbird at byu.edu
Thu Aug 7 00:54:01 BST 2003
I've found a solution that works for me when I have similar problems. The
issue is that the connect function call needs to take a callable object and
self.printMessage("Testing") returns None (which is not a callable object).
You want the call to evaluate at signal time and not at connect time. I'm
attaching a class that I'll call curry. If your familiar with functional
programming then the idea of currying will be familiar to you. If not, just
think of it as combining a function with some arguments and returning another
function that remembers the original arguments when called. Here's an
example. Suppose you have two buttons and you want to connect them to a
single slot, but you want to know which button was pressed when the slot is
executed:
#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)
class foo(QObject):
def __init__(self...):
setup stuff
self.connect(self.button1, SIGNAL("clicked()"),
Curry(self.buttonClickedSlot, "button1"))
self.connect(self.button2, SIGNAL("clicked()"),
Curry(self.buttonClickedSlot,"button2"))
def buttonClickedSlot(self, buttonName):
if buttonName == "button1":
do stuff
elif buttonName == "button2":
do other stuff
In the above example, the same slot gets called when either button is clicked,
but the text passed to the Curry object is used as an argument when the slot
is called. Some signals actually send their own arguments to the slot. In
those cases, the signal arguments are added to the list of arguments passed
to the Curry object and all of them are sent to the slot.
I hope this isn't too confusing. It's helped me a lot in my PyQt programming.
Let me know if it helps or if you need further clarification.
Christian Bird
-------
I've started dabbling with PyQt, but I'm a little confused as to how I can
pass an argument to a function with a button click. For instance, the
following doesn't work:
(snip button code)
self.connect(self.button1, SIGNAL("clicked()"), self.printMessage("Testing"))
def printMessage(text):
print text
(etc.)
Any hints?
:Peter
More information about the PyQt
mailing list