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