get quickly, very fast and directly items in a canvas from a moving button mouse

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

get quickly, very fast and directly items in a canvas from a moving button mouse

Mister Vanhalen
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....

Here is my code 
event is from a bind of 
canvas.bind('<B1-Motion>', lambda event,a="B1m":self.select(event, a))

def select(self, event, typeofevent):
   #=======================================================================
   # get the canvas object 
   #=======================================================================
   canvas = event.widget
        
   #=======================================================================
   # find object close to mouse
   #=======================================================================
   x = canvas.canvasx(event.x)
   y = canvas.canvasy(event.y)
   item =  canvas.find_closest(x, y, halo=None, start=None)


This code works but when my mouse moves too fast, all items are not select. I think self.select is called every x milliseconds, so when it is too fast, it misses some items.
Is there a solution to manage that? I want to get item directly when my mouse is over and button is held.

Thank you for your help,

Eduard


_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: get quickly, very fast and directly items in a canvas from a moving button mouse

Michael Lange
Hi,

Thus spoketh Mister Vanhalen <[hidden email]>
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
little:

* 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))

root.mainloop()
#######

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.

Regards

Michael

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

[Doctors and Bartenders], We both get the same two kinds of customers
-- the living and the dying.
                -- Dr. Boyce, "The Menagerie" ("The Cage"), stardate
unknown
_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss
Reply | Threaded
Open this post in threaded view
|

Re: get quickly, very fast and directly items in a canvas from a moving button mouse

Mister Vanhalen
Hi,

Thank you very much for your answer. I chose your second advice, because the virtual rectangle seemed to be more adapted for my application. But I keep in mind also the tag_bind. 
Thank you again for your help,
Regards,
Eduard

On Sat, Feb 4, 2012 at 9:34 PM, Michael Lange <[hidden email]> wrote:
Hi,

Thus spoketh Mister Vanhalen <[hidden email]>
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
little:

* 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))

root.mainloop()
#######

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.

Regards

Michael

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

[Doctors and Bartenders], We both get the same two kinds of customers
-- the living and the dying.
               -- Dr. Boyce, "The Menagerie" ("The Cage"), stardate
unknown
_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss


_______________________________________________
Tkinter-discuss mailing list
[hidden email]
http://mail.python.org/mailman/listinfo/tkinter-discuss