Tkinter BUG: memory loss for tag bindings in Canvas

Eric Brunel eric.brunel at pragmadev.com
Thu Mar 14 09:56:33 EST 2002


Hi again all,

Considering my memory loss problem with tag bindings, I went a little 
deeper into the Tkinter module and found out what happened: whenever a 
binding is created, a new tcl command is created by the Tkinter/_tkinter 
modules. This command in fact just calls the Python function, but is 
required to do the binding at the tk level, which of course knowns nothing 
about Python. This is this command that cause the memory leak: when the 
graphical item is deleted or even when the binding is cancelled, the 
command is not destoyed in the tcl interpreter...

So I tried to explicitely delete the complete binding by doing something 
like:

----------------------------
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 the binding
f = c.tag_bind(tId, '<Button-1>')
## Print it for debugging purposes
print f
## Explicitely remove the binding
c.tag_unbind(tId, '<Button-1>', f)

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

This doesn't work, and here is the result:

if {"[136128196foo %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y 
%D]" == "break"} break
 
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

The "if {...} ..." is the result of the print. If I understand correctly, 
the binding at the tk level is not made directly to the created command, 
but to this expression, allowing Python callbacks to stop executing the 
bindings by doing "return 'break'". But by doing so, the result of 
"c.tag_bind(tId, '<Button-1>'" is not the name of the created tcl command 
(which seems to be "136128196foo"), and so cannot be used in the tag_unbind 
method, which tries to delete the command, resulting in the traceback above.

To me, this sounds like a bug, doesn't it? Any maintainers of Tkinter 
around here?

TIA
 - eric -






More information about the Python-list mailing list