This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Wrong result for Canvas.tag_bind(t, s)
Type: Stage:
Components: Tkinter Versions:
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: akuchling Nosy List: akuchling, ebrunel
Priority: normal Keywords:

Created on 2002-03-18 09:07 by ebrunel, last changed 2022-04-10 16:05 by admin. This issue is now closed.

Messages (4)
msg9753 - (view) Author: Eric Brunel (ebrunel) Date: 2002-03-18 09:07
When a binding is defined for a tag in a Tkinter 
Canvas, trying to get the callback using the 
"tag_bind" method with 2 parameters returns a useless 
value:

----------------------------
from Tkinter import *

root = Tk()

## Create the canvas
c = Canvas(root)
c.pack()

## Create the item
tId = c.create_text(100, 100, text='spam')

## Create the binding
def foo(event): print 'bar'
c.tag_bind(tId, '<Button-1>', foo)

## Get and print the binding
print c.tag_bind(tId, '<Button-1>')

root.mainloop()
---------------------------

The programs prints something looking like: 'if 
{"[136128196foo %# %b %f %h %k %s %t %w %x %y %A %E 
%K %N %W %T %X %Y %D]" == "break"} break'. Trying to 
pass this value as the third parameter of tag_unbind 
for example results in a TclError:

Traceback (most recent call last):
  File "tkCanvasBindings2.py", line 16, in ?
    c.tag_unbind(tId, '<Button-1>', f)
  File "/usr/local/lib/python2.1/lib-tk/Tkinter.py", 
line 1904, in 
tag_unbind
    self.deletecommand(funcid)
  File "/usr/local/lib/python2.1/lib-tk/Tkinter.py", 
line 297, in 
deletecommand
    self.tk.deletecommand(name)
TclError: can't delete Tcl command

This happens apparently on all platforms (tried 
Win2K, Linux Mandrake 8.0 and Solaris 2.7).

msg9754 - (view) Author: A.M. Kuchling (akuchling) * (Python committer) Date: 2002-03-22 16:44
Logged In: YES 
user_id=11375

I don't think this is actually a bug, and the return 
value of tag_bind really is useless.  tag_bind(t,s) 
returns the command bound to that sequence.  
Tkinter.py supports a feature where a binding can 
return the string "break" if no further bound function 
should be invoked, so when adding a binding, Python has 
to synthesize the 'if {123456foo ...}' Tcl command, and 
that's what tag_bind returns.

I think your example code should be written as:

bind_id = c.tag_bind(tId, '<Button-1>', foo)

And then refer to bind_id when you need to delete the 
binding.  

Was your example usage of tag_bind() described in some 
documentation, or in a demo script somewhere?  
Maybe that script or documentation needs to be fixed.
msg9755 - (view) Author: Eric Brunel (ebrunel) Date: 2002-03-22 17:12
Logged In: YES 
user_id=489050

In fact, I saw this problem when trying to delete the 
bindings made for a Canvas: I noticed that when refreshing 
several times a canvas by deleting, then recreating all 
the items (including the bindings), the occupied memory 
increased with no apparent reason. So I dived into 
Tkinter.py, and found out that Tcl commands were created 
for each binding, but were only deleted either when 
deleting the Canvas (which I couldn't do), or when calling 
the tag_unbind method with the tagOrId, the sequence *and* 
the Tcl command name. So I tried to get this command name 
by calling tag_bind, and saw that the result was not what 
I expected.
The solution to remember the result of the call to 
tag_bind creating the binding provides a solution to this 
problem. It may just be a bit strange to explicitely 
remember the bindings in the application, since Tk/Tkinter 
already remembers them. It may also seem strange to get 
via tag_bind something that is completely useless at the 
Python level...

Anyway, thanks a lot.
msg9756 - (view) Author: A.M. Kuchling (akuchling) * (Python committer) Date: 2002-03-22 17:53
Logged In: YES 
user_id=11375

You're welcome.  Closing this bug report...
History
Date User Action Args
2022-04-10 16:05:06adminsetgithub: 36272
2002-03-18 09:07:59ebrunelcreate