Canvas Object Tags: Help for Rookie

Abel Daniel abli at freemail.hu
Wed Dec 18 17:59:55 EST 2002


John Smith (someone at microsoft.com) wrote:
> I am goofing around with the canvas class and trying to reference line
> objects drawn on a canvas by their tags.  I thought the easiest appraoch
> would be to give each new line an tag set by an integer counter.  A short
> version of my code looks like:
Maybe you snipped too much, the code you posted gives other errors.

Anyway, as far i could tell from the code, your problem might be here:
( in myCanvas.__init__() )
>     self.btn.bind('<Button-1>', self.lineupdate(tagid))
                                  ^^^^^^^^^^^^^^^^^^^^^^
Here you should be supplying a method, and not call it. That is, write
self.foo and _not_ self.foo() . These two things are different, try it
out at the interactive prompt.
What you need is more like:

 self.btn.bind('<Button-1>', lambda s, e, t=tagid: self.lineupdate(s, t, e) )
 
lambda creates an "anonymous function" which takes three args. The
callback will get 2, so the third will have the default value.

The error message arises because when you do
> mc = myCanvas(root)
myCanvas.__init__ will run, and with the code you have now, call
lineupdate when creating the button.
lineupdate looks for the tag and fails, which shouldn't be suprising, as
you want to create the line _afterwards_ with
> mc.firstline()

OTOH if you only need to have unique tags for each object on the canvas,
you dont have to do it this way. Every object has a tag (called id) which is
garanteed to be unique. This is returned by the constructor, so you only
have to store that, for example by:
lines=[]
...other code...
lines.append(self.canvas.create_line( ...args...) )
...other code...
for i in lines:
    self.canvas.coords(i)

to print all the coordinates.

In fact, by experimenting with the interactive prompt, it looks like
using integers for tags is as extremly bad idea, and it will silently
fail. The id's are simply integers, so if you would use an integer as a
tag, it would get mixed up with some id. It looks like an integer
supplyed will be silently ignored. (However, i dont see this documented
anywhere)

Anyway, i would suggest getting "Tkinter reference: a GUI for Python"
from http://www.nmt.edu/tcc/help/pubs/lang.html
(direct link:http://www.nmt.edu/tcc/help/pubs/tkinter.pdf)

(i got that trick with lambda from there, its called "the extra
arguments trick", 83. page)

abli
abli at freemail.hu




More information about the Python-list mailing list