Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Is it possible to call a function from a Tkinter widget.bind and include args???

5 views
Skip to first unread message

G. Willoughby

unread,
Feb 11, 2002, 3:23:50 PM2/11/02
to
Is it possible to call a function from a Tkinter widget.bind and include
args???
i.e. i want to do something like this:

def printButtonAndCoords(event, button):
print "you rolled over %s and coords are %d:%d" % button, event.x,
eventy

Button1.bind("<Enter>", printButtonAndCoords("button1"))
Button2.bind("<Enter>", printButtonAndCoords("button2"))

is this possible???

i have tried this: but it seems a bit crap!:

[snip]
...
self.newFileButton.bind("<Enter>", self.getMouseCoords)
self.newFileButton.bind("<Leave>", self.deleteToolTip)
...
def getMouseCoords(self, event):
self.xPos=event.x_root-5
self.yPos=event.y_root+5
self.showToolTip(str(event.widget), self.xPos, self.yPos)

def showToolTip(self, id, xPos, yPos):
if id==".8387596.7951612": #this looks very breakable!
self.toolTip=tkToolTip.toolTip(xPos, yPos, liftAbove=self.master,
text="Create a new file")

def deleteToolTip(self, event):
self.toolTip.destroyToolTip()
del self.toolTip
[/snip]

help... :'-(

G. Willoughby


Martin v. Loewis

unread,
Feb 11, 2002, 4:58:39 PM2/11/02
to
"G. Willoughby" <s...@NOSPAM.freeuk.com> writes:

> Is it possible to call a function from a Tkinter widget.bind and include
> args???
> i.e. i want to do something like this:
>
> def printButtonAndCoords(event, button):
> print "you rolled over %s and coords are %d:%d" % button, event.x,
> eventy
>
> Button1.bind("<Enter>", printButtonAndCoords("button1"))
> Button2.bind("<Enter>", printButtonAndCoords("button2"))
>
> is this possible???

The common idiom is

Button1.bind("<Enter>", lambda ev:printButtonAndCoords(ev,"button1"))
Button2.bind("<Enter>", lambda ev:printButtonAndCoords(ev,"button2"))

Notice that event.widget will give you the widget that was the source
of the event, so you may not need additional parameters at all.

Regards,
Martin

Fredrik Lundh

unread,
Feb 11, 2002, 5:03:02 PM2/11/02
to
G. wrote:

> Button1.bind("<Enter>", printButtonAndCoords("button1"))

this calls the printButtonAndCoords function, and passes the
result to the bind function.

(well, to be precise, it gives a TypeError exception)

try this instead:

Button1.bind("<Enter>", lambda e: printButtonAndCoords(e, "button1"))
Button2.bind("<Enter>", lambda e: printButtonAndCoords(e, "button2"))

(the lambda statement creates a callable object taking one
argument, which it passes on to the printButtonAndCoords
function)

you might prefer writing this as

callback = lambda e: printButtonAndCoords(e, "button1")
Button1.bind("<Enter>", callback)
callback = lambda e: printButtonAndCoords(e, "button2")
Button2.bind("<Enter>", callback)

or even:

def callback(e):
printButtonAndCoords(e, "button1")
Button1.bind("<Enter>", callback)

def callback(e):
printButtonAndCoords(e, "button2")
Button2.bind("<Enter>", callback)

hope this helps!

</F>

<!-- (the eff-bot guide to) the python standard library:
http://www.pythonware.com/people/fredrik/librarybook.htm
-->


Eric Brunel

unread,
Feb 12, 2002, 5:03:19 AM2/12/02
to
Hi,

G. Willoughby wrote:

> Is it possible to call a function from a Tkinter widget.bind and include
> args???
> i.e. i want to do something like this:
>
> def printButtonAndCoords(event, button):
> print "you rolled over %s and coords are %d:%d" % button, event.x,
> eventy
>
> Button1.bind("<Enter>", printButtonAndCoords("button1"))
> Button2.bind("<Enter>", printButtonAndCoords("button2"))
>
> is this possible???

Since you didn't mention your Python version, maybe the lambda stuff
provided by Martin and Fredrik won't work (with pre-2.0 versions, the
lambda may not have the printButtonAndCoords function in its namespace,
isn't it?).
So here is another solution I used quite a lot. with pre-2.0 Python It
involves the creation of a callback class:

class GenericCallback:
def __init__(self, callback, *firstArgs):
self.__callback = callback
self.__firstArgs = firstArgs
def __call__(self, *lastArgs):
apply(self.__callback, self.__firstArgs + lastArgs)

Then you make your binding like follows:

Button1.bind("<Enter>", GenericCallback(printButtonAndCoords, "button1"))

Your printButtonAndCoords function should then take the string as first
argument and the Tkinter event as second. The binding will "call" the
instance of GenericCallback, i.e. call its __call__ method, which will in
turn call printButtonAndCoords with the arguments provided in the
constructor, then in the actual call.

The GenericCallback class is also generic enough to have many other uses
(in fact everywhere you must provide a function).

HTH
- eric -

G. Willoughby

unread,
Feb 12, 2002, 5:22:22 PM2/12/02
to
Thankyou all, your comments are very helpful! :) Especially the
GenericCallback class!

G. Willoughby


"G. Willoughby" <s...@NOSPAM.freeuk.com> wrote in message
news:a4995n$gbg$1...@news5.svr.pol.co.uk...

0 new messages