[Tkinter-discuss] get quickly, very fast and directly items in a canvas from a moving button mouse

Michael Lange klappnase at web.de
Sat Feb 4 21:34:16 CET 2012


Thus spoketh Mister Vanhalen <mistervanhalen at gmail.com> 
unto us on Sat, 4 Feb 2012 14:33:43 +0100:

> Hello everyone,
> I have got a canvas, where I created some items (rectangles and
> letters). I want to catch quickly and directly every item when I move
> my mouse holding a button.
> I managed to do something but when the movement is too fast, all items
> are not selected....

there seems to be a certain point where even in the simplest example
some events fail to be handled, not sure if it is Tk- or window manager
related, but here it is the same, if the mouse is *very* fast, the event
might be missed.

>From your example it is hard to tell if there is an additional problem in
your event callback that slows things down further, because the snippet
does not show any visible effect when an item is being selected. Maybe in
your "real world" code some bottleneck is in what happens to "item" later
within your select() method. Maybe some optimization might help.

Two things come to mind which you might try to improve things at least a

* first, using the canvases tag_bind() method instead of bind(). 
* second, try to reduce the amount of Tk calls within the select()
callback; in cases where optimization becomes an issue, tk callbacks
prove to be processed relatively slow and often considerable improvements
can be achieved by storing some Tk related information in Python objects
instead of querying them every time through Tk, or sometimes a trick can
be used to pass them directly to the callback, as in this example:

from Tkinter import *

root = Tk()
canv = Canvas(root)
canv.pack(fill='both', expand=1)
t1 = canv.create_text(10, 10, text='foobar', anchor='nw')
t2 = canv.create_text(10, 60, text='foobar', anchor='nw')
t3 = canv.create_text(10, 110, text='foobar', anchor='nw')
t4 = canv.create_text(10, 160, text='foobar', anchor='nw')

def select(event, item):
    print 'selected', item

for t in (t1, t2, t3, t4):
    canv.tag_bind(t, '<Any-Motion>',
                   lambda event, item=t : select(event,item))


Now, whem you talk about "selecting" a totally different approach comes
to mind; it sounds to me like you want to draw some kind of "virtual
rectangle" across the canvas to select all the items within this
rectangle, much as you would do in a file browser to select items? If
yes, then maybe you would better actually draw such a rectangle, and then
later "select" all the items within, maybe the ButtonPress and
ButtonRelease event's coords are easier to track than all the coords
within the motion. Just a guess of course.



.-.. .. ...- .   .-.. --- -. --.   .- -. -..   .--. .-. --- ... .--. . .-.

[Doctors and Bartenders], We both get the same two kinds of customers
-- the living and the dying.
		-- Dr. Boyce, "The Menagerie" ("The Cage"), stardate

More information about the Tkinter-discuss mailing list