Unbinding Tkinter default bindings for Listbox

R

Roger

Hi Everyone,

I have a behavior associated with a default binding with Tkinter
Listbox that I want to get rid of but I can't no matter if I return
"break" on the binding or unbind it directly. If you have a Listbox
where the bounding box is not completely revealed in the window that
holds it and you use the mouse to drag the list box, the contents of
the listbox will move in the X direction to reveal the area that's
hidden. After searching the internet for hours I found the behavior I
want to remove is a default binding as described here:

http://tcltk.free.fr/man/TkCmd/listbox.php3

"[3] If the mouse leaves the listbox window with button 1 down, the
window scrolls away from the mouse, making information visible that
used to be off-screen on the side of the mouse. The scrolling
continues until the mouse re-enters the window, the button is
released, or the end of the listbox is reached. "

After further searching I found that the code for this in tcl is
described here:

http://www.openmash.org/lxr/source/library/listbox.tcl?c=tk8.3

50 bind Listbox <B1-Motion> {
51 set tkPriv(x) %x
52 set tkPriv(y) %y
53 tkListboxMotion %W [%W index @%x,%y]
54 }

Now I've found no way to successfully unbind B1-Motion from the
listbox, as I said above. Nor return "break" on receiving the event.
I do want to eventually have my own B1-Motion binding applied to the
listbox for a different reason (with add='+' if necessary). My next
step was to see if I could just unbind B1-Motion then programmatically
delete tkListboxMotion in my code but tkListboxMotion is not available
in the Tkinter source (it's part of a compiled binary I can't reach?).

Any help would be greatly appreciated. Thanks!
Roger.
 
J

James Stroud

Roger said:
Hi Everyone,

I have a behavior associated with a default binding with Tkinter
Listbox that I want to get rid of but I can't no matter if I return
"break" on the binding or unbind it directly. If you have a Listbox
where the bounding box is not completely revealed in the window that
holds it and you use the mouse to drag the list box, the contents of
the listbox will move in the X direction to reveal the area that's
hidden. After searching the internet for hours I found the behavior I
want to remove is a default binding as described here:

http://tcltk.free.fr/man/TkCmd/listbox.php3

"[3] If the mouse leaves the listbox window with button 1 down, the
window scrolls away from the mouse, making information visible that
used to be off-screen on the side of the mouse. The scrolling
continues until the mouse re-enters the window, the button is
released, or the end of the listbox is reached. "

After further searching I found that the code for this in tcl is
described here:

http://www.openmash.org/lxr/source/library/listbox.tcl?c=tk8.3

50 bind Listbox <B1-Motion> {
51 set tkPriv(x) %x
52 set tkPriv(y) %y
53 tkListboxMotion %W [%W index @%x,%y]
54 }

Now I've found no way to successfully unbind B1-Motion from the
listbox, as I said above. Nor return "break" on receiving the event.
I do want to eventually have my own B1-Motion binding applied to the
listbox for a different reason (with add='+' if necessary). My next
step was to see if I could just unbind B1-Motion then programmatically
delete tkListboxMotion in my code but tkListboxMotion is not available
in the Tkinter source (it's part of a compiled binary I can't reach?).

Any help would be greatly appreciated. Thanks!
Roger.

You can directly send commands to the Tcl interpreter via the call
method of the tk attribute of any Tkinter widget. For example:


py> from Tkinter import *
py> tk = Tk()
py> b = Button(tk)
py> b.pack()
py> b.tk
<tkapp object at 0xd57720>
py> b.tk.call('bind', 'Listbox', '<B1-Motion>')
'\n set tk::priv(x) %x\n set tk::priv(y) %y\n tk::ListboxMotion
%W [%W index @%x,%y]\n'
py> b.tk.call('bind', 'Listbox', '<B1-Motion>', _)
''


James



--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com
 
R

Roger

You want b.tk.call('bind', 'Listbox', '<B1-Motion>', "") of course.

James

--
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com

Knowing this is actually extremely useful (looking at Tkinter.py i see
this is equivalent to the unbind method). Unfortunately it's not
working to unbind B1-Motion from Listbox even though I get the same
output results as you've gotten above. =(

Thanks a ton James. This is still very educational to me.

Roger.
 
R

Roger

I'm sorry for harassing the list but any suggestions would be greatly
appreciated. =)
 
J

James Stroud

Roger said:
I'm sorry for harassing the list but any suggestions would be greatly
appreciated. =)

I just checked the behavior you are describing. It seems that you want
to unbind the <Leave> event to stop the autoscrolling when you leave the
listbox. E.g.:

from Tkinter import *
tk = Tk()
lb = Listbox(tk)
lb.pack()
tk.tk.call('bind', str(lb), '<Leave>', "break")
for i in range(12):
lb.insert(END, str(i))


Sorry for not reading more carefully.

James
 
J

James Stroud

James said:
tk.tk.call('bind', str(lb), '<Leave>', "break")

Which is equivalent to

lb.bind('<Leave>', "break")

But I checked and overriding the default behavior of Listbox does not
work (tk.tk.call('bind', "Listbox", '<Leave>', "break")).

So I would subclass Listbox and do the bindings in the __init__:

class MyListbox(Listbox):
def __init__(self, *args, **kwargs):
Listbox.__init__(self, *args, **kwargs)
self.bind('<Leave>', "break")


James
 
R

Roger

Which is equivalent to

lb.bind('<Leave>', "break")

But I checked and overriding the default behavior of Listbox does not
work (tk.tk.call('bind', "Listbox", '<Leave>', "break")).

So I would subclass Listbox and do the bindings in the __init__:

class MyListbox(Listbox):
   def __init__(self, *args, **kwargs):
     Listbox.__init__(self, *args, **kwargs)
     self.bind('<Leave>', "break")

James

You sir are awesome. Thank you so much. I've so far been really good
at troubleshooting Tkinter, the library has really melded with my
thinking naturally since I started using Python on a regular basis a
year ago. I had mixed feelings about asking for help on this because
I wanted so badly to figure it out myself but I became so exasperated
especially after combing through the TCL source to no affect. Now
that you've given me the correct solution it seems like the Leave
event should have been a natural binding for me to break in all my
fiddling.

Ah well, it's a lesson I won't forget thanks to you. Thanks so much
again, you're help is invaluable. =D

Roger.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,998
Latest member
MarissaEub

Latest Threads

Top