passing data to Tkinter call backs
Bruno Desthuilliers
bruno.42.desthuilliers at websiteburo.invalid
Wed Jun 9 08:50:08 EDT 2010
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" !-)
More information about the Python-list
mailing list