passing data to Tkinter call backs
Hi, If this is the wrong place for Tkinter in python please direct me elsewhere! 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? Or am I reduced to using spit global data? A Singleton is just Global Data by other means. -- Nick Keighley This led to packs of feral Global Variables roaming the address space. -- http://mail.python.org/mailman/listinfo/python-list
Re: passing data to Tkinter call backs
Nick Keighley a écrit : Hi, If this is the wrong place for Tkinter in python please direct me elsewhere! 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: Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) [GCC 4.3.3] on linux2 Type help, copyright, credits or license for more information. 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 ??? Or am I reduced to using spit global data? A Singleton is just Global Data by other means. from functools import partial data = dict() def handle_event(event, data): ... data['foo'] = bar ... print event ... p = partial(handle_event, data=data) p(e) __main__.Event object at 0xb75383ec data {'foo': 'bar'} Note that data doesn't have to be global here. -- http://mail.python.org/mailman/listinfo/python-list
Re: passing data to Tkinter call backs
On 9 June, 10:35, Bruno Desthuilliers bruno. 42.desthuilli...@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 Or am I reduced to using spit global data? A Singleton is just Global Data by other means. 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 but a little more elegantly? p(e) __main__.Event object at 0xb75383ec data {'foo': 'bar'} Note that data doesn't have to be global here. # callback for mouse click event def mouse_clik_event (event, data) : dosomething (event.x, event.y, data) draw_stuff (display, data) data = Data(6.0, 0.2, 0.3) draw_stuff (display, data) # snag mouse display.canvas.bind(ButtonRelease-1, lambda event: mouse_clik_event (event, mandelbrot)) -- There are known knowns; there are things we know we know. We also know there are known unknowns; that is to say we know there are some things we do not know. But there are also unknown unknowns -- the ones we don't know we don't know. -- http://mail.python.org/mailman/listinfo/python-list
Re: passing data to Tkinter call backs
Nick Keighley a écrit : On 9 June, 10:35, Bruno Desthuilliers bruno. 42.desthuilli...@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 !-) -- http://mail.python.org/mailman/listinfo/python-list
Re: passing data to Tkinter call backs
On 9 June, 13:50, Bruno Desthuilliers bruno. 42.desthuilli...@websiteburo.invalid wrote: Nick Keighley a écrit : On 9 June, 10:35, Bruno Desthuilliers bruno. 42.desthuilli...@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. -- http://mail.python.org/mailman/listinfo/python-list
Re: passing data to Tkinter call backs
Nick Keighley a écrit : On 9 June, 13:50, Bruno Desthuilliers bruno. (snip) 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... Well... Python is not Scheme - specially wrt/ lambdas and closures. While it has some restricted support for some FP idioms, Python is definitly an OO language. FWIW, you could implement the functool.partial class using closures / HOF (and it's been done before), but it's easier and just more obvious to take the OO route here. -- http://mail.python.org/mailman/listinfo/python-list
Re: passing data to Tkinter call backs
On Jun 9, 4:23 am, Nick Keighley nick_keighley_nos...@hotmail.com wrote: 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? I don't know how you're triggering redraws but you need to read this first... w.update() This method forces the updating of the display. It should be used only if you know what you're doing, since it can lead to unpredictable behavior or looping. It should never be called from an event callback or a function that is called from an event callback. w.update_idletasks() Some tasks in updating the display, such as resizing and redrawing widgets, are called idle tasks because they are usually deferred until the application has finished handling events and has gone back to the main loop to wait for new events. If you want to force the display to be updated before the application next idles, call the w.update_idletasks() method on any widget. -- http://mail.python.org/mailman/listinfo/python-list