Tkinter unbinding

Bad Mutha Hubbard badmuthahubbard at usenet.cnntp.org
Fri Dec 19 10:02:35 CET 2008


Bad Mutha Hubbard wrote:

> Roger wrote:
>
>> I've done a lot of googling for this topic and I fear that it's not
>> possible.  I have a widget that is overloaded with several bindings.
>> I want to be able to unbind one method form the same Event without
>> destroying all the other bindings to the same event that's associated
>> to the same widget.
>>
>> For example:
>>
>> import Tkinter
>>
>> def test():
>>         print 'test'
>>
>> def test2():
>>         print 'test2'
>>
>> root = Tkinter.Tk()
>> funcid1 = root.bind("<1>", lambda e: test())
>> funcid2 = root.bind("<1>", lambda e: test2(), add='+')
>> root.unbind("<1>", funcid2)
>> root.mainloop()
>>
>> When run neither <1> binding will exist against the root because the
>> unbind will unbind all the functions associated with that event.
>> However, in this example, I only want to unbind test2 not test1.
>>
>> Any help is greatly appreciated.  Thanks!
>> Roger.
>
> I believe you've discovered a bug.  Aside from recommending trying
> wxWidgets, here's the source of the unbind function in Tkinter.py:
>
>     def unbind(self, sequence, funcid=None):
>         """Unbind for this widget for event SEQUENCE  the
>         function identified with FUNCID."""
>         self.tk.call('bind', self._w, sequence, '')
>         if funcid:
>             self.deletecommand(funcid)
>
> -------------------------------------------
> First, it replaces all bindings for the sequence with the empty string,
> i.e., it deletes all bindings for that event unconditionally.  THEN it
> calls deletecommand() with the funcid, who knows what that does.  My Tcl
> is not so sharp.
> I have an idea for a workaround, let me see if it works...
> -Chuckk

Alas, my workaround doesn't work either.  Tkinter.py also states that
calling bind with only an event sequence will return all bindings for
that sequence; I was thinking I could then remove the function in
question from that list and call bind again with each of the
functions in the remaning list as argument. I had
high hopes. The return value of calling bind with no target function
is just about Tcl nonsense:

#!/usr/bin/env python

import Tkinter

def test(event):
        print 'test'

def test2(event):
        print 'test2'

root = Tkinter.Tk()
funcid1 = root.bind("<1>", test)
funcid2 = root.bind("<1>", test2, add='+')
print funcid1, funcid2

bound = root.bind('<Button-1>')
print "bound:", bound
#root.unbind("<1>", funcid=funcid2)
root.mainloop()

---------------------------
Note that I took out the lambdas and gave event arguments to the
functions; if you did that on purpose, because you need to call the same
functions without events, then just ignore that...
SO, the other workaround, which I've used, is to bind the event to a
generic function, and have that generic function conditionally call
the functions you want. I'll go back and try to make an example from
your example. -Chuckk



More information about the Python-list mailing list