newbie, re: tkinter canvas

Steven Taschuk staschuk at telusplanet.net
Fri Mar 7 23:41:11 EST 2003


Quoth Locash:
  [...]
> When I make the following changes, suddenly every pick I make wipes
> all other images from the canvas.  Can anyone explain to me why this
> happens?

I think it's because your PhotoImage objects imgL and imgD are
getting garbage collected.  If memory serves, for some reason
canvases don't keep references to image objects, so you have to
manage them yourself.  With the code as written, you're keeping
references in self.emptyWorld and self.currentGen, and everything
is fine; with the changes you wish to make, those references
disappear and with them, the objects.

(I wonder whether the line
	self.world.img = imgL                       
was intended to deal with this possibility.  But if so, it won't
work -- a new imgL is created on each execution of createLife, and
so the old one will be garbage collected.)

Accordingly, I suggest the following changes, which do, in fact,
make the symptom go away.

(And, by the way, a Frame subclass really shouldn't grid itself;
let the caller control the geometry management.  It's not, after
all, of interest to the Frame how it gets placed in its parent
window.)

    --- life-orig.py	Fri Mar  7 21:28:12 2003
    +++ life.py	Fri Mar  7 21:35:46 2003
    @@ -12,37 +12,34 @@

         def createWidgets(self):        

    -        imgD = PhotoImage(file='death.gif')
    -        
    -        self.world = Canvas (self, height=406, width=406, bg=
    -"#eeeeee", cursor="hand1")
    +        self.world = Canvas (self, height=406, width=406,
    +                bg="#eeeeee", cursor="hand1")
             self.world.grid (row=0, column=0, columnspan=6)
             self.world.bind ("<Button-1>", self.createLife)

    +        self.world.imgD = PhotoImage(file='death.gif')
    +        self.world.imgL = PhotoImage(file='life.gif')
    +        
             for x in range (0,40):
                 self.emptyWorld.append([])
                 self.currentGen.append([])
                 for y in range (0,40):      
                     self.world.create_image(((x+1)*10), ((y+1)*10),
    -image=imgD)
    -                self.emptyWorld[x].append(imgD)
    +                    image=self.world.imgD)
    +                self.emptyWorld[x].append(0)
                     self.currentGen = self.emptyWorld       
    -        self.world.img=imgD

         def createLife(self, event):

    -        imgL = PhotoImage(file='life.gif')
    -        
             x = int(((event.x + 5)/10))*10
             y = int(((event.y + 5)/10))*10

             for i in range (0, len(self.currentGen)):
                 for j in range (0, len(self.currentGen[i])):
                     if x == (i*10) and y == (j*10):                     
    -                    self.world.create_image(x, y, image=imgL)
    -                    self.currentGen[i][j] = imgL                    
    +                    self.world.create_image(x, y, image=self.world.imgL)
    +                    self.currentGen[i][j] = 1
                     else: pass
    -        self.world.img = imgL                       

     app = Application() # Instantiate the application class
     app.master.title("Conway's Game of Life")

-- 
Steven Taschuk                             staschuk at telusplanet.net
"I may be wrong but I'm positive."  -- _Friday_, Robert A. Heinlein





More information about the Python-list mailing list