passing data to Tkinter call backs

Nick Keighley nick_keighley_nospam at hotmail.com
Wed Jun 9 09:19:46 EDT 2010


On 9 June, 13:50, Bruno Desthuilliers <bruno.
42.desthuilli... at websiteburo.invalid> wrote:
> Nick Keighley a écrit :
>
>
>
>
>
> > On 9 June, 10:35, Bruno Desthuilliers <bruno.
> > 42.desthuilli... at websiteburo.invalid> wrote:
> >> Nick Keighley a crit :
>
> >>> I'm trapping mouse clicks using
> >>> canvas.bind("<ButtonRelease-1>", mouse_clik_event)
> >>> def mouse_clik_event (event) :
> >>>      stuff
> >>> What mouse_clik_event does is modify some data and trigger a redraw.
> >>> Is there any way to pass data to the callback function? Some GUIs give
> >>> you a user-data field in the event, does Tkinter?
> >> Never used TkInter much, but if event is a regular Python object, you
> >> don't need any "user-data field" - just set whatever attribute you want, ie:
> > [...]
> >>  >>> class Event(object): pass
> >> ...
> >>  >>> e = Event()
> >>  >>> e.user_data = "here are my data"
> >>  >>> e.user_data
> >> 'here are my data'
>
> >> But I fail to see how this would solve your problem here - where would
> >> you set this attribute ???
>
> > Those other GUIs also give you a mechanism to pass the data. Say
> > another parameter in the bind call
>
> Ok, so my suggestion should work, as well as any equivalent (lambda,
> closure, custom callable object etc).
>
> >>  >>> from functools import partial
> >>  >>> data = dict()
> >>  >>> def handle_event(event, data):
> >> ...     data['foo'] = "bar"
> >> ...     print event
> >> ...
> >>  >>> p = partial(handle_event, data=data)
>
> > ah! the first time I read this I didn't get this. But in the mean time
> > cobbled something together using lambda. Is "partial" doing the same
> > thing
>
> Mostly, yes - in both cases you get a callable object that keeps a
> reference on the data. You could also use a closure:
>
> def make_handler(func, data):
>     def handler(event):
>         func(event, data)
>     return handler
>
> def mouse_clik_event (event, data) :
>      dosomething (event.x, event.y, data)
>      draw_stuff (display, data)
>
> display.canvas.bind(
>    "<ButtonRelease-1>",
>     make_handler(mouse_click_event, data)
>    )
>
> > but a little more elegantly?
>
> Depending on your own definition for "elegantly"...
>
> Note that the lambda trick you used is very idiomatic - functool.partial
> being newer and probably not as used - so one could argue that the most
> common way is also the most "elegant" !-)

I'm somewhat newbie at Python but I'd seen lambda elsewhere (scheme).
I like the closure trick... I'm using "Python In a Nutshell" as my
guide.






More information about the Python-list mailing list