[PyKDE] Sending an argument to a function with a button click

Frederick Polgardy Jr polgardy at bodacion.com
Thu Aug 7 02:25:00 BST 2003


You can accomplish this a bit more simply with a lambda:

   self.connect(self.button1, SIGNAL("clicked()"),
            lambda: self.buttonClickedSlot("button1"))
   self.connect(self.button2, SIGNAL("clicked()"),
            lambda: self.buttonClickedSlot("button2"))

Though now that I think about it, the lambda might need to be squirreled 
away somewhere so as not to be cleaned up by the reference counter.  Same 
goes for the Curry example though.

Fred

On Wednesday 06 August 2003 17:46, Christian Bird wrote:
> 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
>
> _______________________________________________
> PyKDE mailing list    PyKDE at mats.imk.fraunhofer.de
> http://mats.imk.fraunhofer.de/mailman/listinfo/pykde




More information about the PyQt mailing list