[Tkinter-discuss] Unbinding Individual Events
Michael Lange
klappnase at web.de
Fri May 11 11:59:30 CEST 2012
Hi,
Thus spoketh Lion Kimbro <lionkimbro at gmail.com>
unto us on Wed, 9 May 2012 19:19:55 -0700:
(...)
> So my thought to systematize this is:
>
> A. Make a function (fn-A) for making a Python list out all binding
> strings on a widget-sequence pair.
> B. Make a function (fn-B) that constructs the binding string for a
> given function binding.
> C. Patch(/replace) widget.unbind so that it retrieves all binding
> strings (via fn-A), and then removes the string that matches fn-B
> (funcid), and then rebind the widget via the new list
>
> I think that should work.
>
> My main concern is that, if _tkinter does any reference counting on
> function uses, then there is a memory hole.
>
> Thoughts?
As far as memory holes are concerned, I think cleanly unbinding each
single command, so deletecommand() will be executed, should do the trick.
Although I agree that the behavior of unbind() is not intuitive, I
think that making unbind() backwards incompatible is not a good
idea ;)
I set up a quick example, it is not perfect but seems to work ok for a
start; you see, instead of changing unbind(), I called the function that
does the work remove_binding() for now.
Best regards
Michael
##########################################
from Tkinter import *
root = Tk()
l = Listbox(root)
l.pack()
def cmd1(event):
print '1'
def cmd2(event):
print '2'
def cmd3(event):
print '3'
b1 = l.bind('<Motion>', cmd1)
b2 = l.bind('<Motion>', cmd2, 1)
b3 = l.bind('<Motion>', cmd3, 1)
def bindings(widget, seq):
return [x for x in widget.bind(seq).splitlines() if x.strip()]
def _funcid(binding):
return binding.split()[1][3:]
def remove_binding(widget, seq, index=None, funcid=None):
b = bindings(widget, seq)
if not index is None:
try:
binding = b[index]
widget.unbind(seq, _funcid(binding))
b.remove(binding)
except IndexError:
print 'Binding #%d not defined.' % index
return
elif funcid:
binding = None
for x in b:
if _funcid(x) == funcid:
binding = x
b.remove(binding)
widget.unbind(seq, funcid)
break
if not binding:
print 'Binding "%s" not defined.' % funcid
return
else:
raise ValueError, 'No index or function id defined.'
for x in b:
widget.bind(seq, '+'+x, 1)
def test1(event):
remove_binding(l, '<Motion>', 0)
def test2(event):
remove_binding(l, '<Motion>', None, b1)
l.bind('<1>', test1)
l.bind('<3>', test2)
root.mainloop()
###############################################
.-.. .. ...- . .-.. --- -. --. .- -. -.. .--. .-. --- ... .--. . .-.
Totally illogical, there was no chance.
-- Spock, "The Galileo Seven", stardate 2822.3
More information about the Tkinter-discuss
mailing list