Problem displaying images with TkInter
David
esuvs at yahoo.co.uk
Thu Mar 4 19:53:44 EST 2004
Ok, that's working now. Thanks for the tip!
David
Eric Brunel wrote:
> David wrote:
>> Hi,
>> I'm new to python so I'm probably making a fairly simple mistake,
>> but
>> look at the example below. It simply displays a rectangle and an image.
>>
>> -------------------------------------------------
>> from Tkinter import *
>>
>> root = Tk()
>>
>> c = Canvas(root, width=1024, height = 1024)
>> c.pack()
>>
>> c.create_rectangle(10,10,50,50)
>> mudPhoto = PhotoImage(file="/root/metropolis/mud.gif")
>> c.create_image(50, 50, anchor=NW, image=mudPhoto)
>>
>> root.mainloop()
>> -----------------------------------------------
>>
>> Now I try to modify it so that the image and rectangle only appear when I
>> click the mouse on the canvas. I use the following code:
>>
>> -----------------------------------------------
>> from Tkinter import *
>>
>> root = Tk()
>>
>> def OnClick(event):
>> print "click!!!"
>> c.create_rectangle(10,10,50,50)
>> mudPhoto = PhotoImage(file="/root/metropolis/mud.gif")
>> c.create_image(50, 50, anchor=NW, image=mudPhoto)
>>
>> c = Canvas(root, width=1024, height = 1024)
>> c.pack()
>> c.bind("<Button-1>",OnClick)
>> root.mainloop()
>> ----------------------------------------------
>>
>> However when I click the mouse it prints 'click!!!' and draws the
>> rectangle as expected. However it doesn't draw the image! Does anyone
>> have any idea why this would be?
>
> This used to be a FAQ, but I can't it anymore (anyone knows where it has
> gone?).
>
> The problem lies in the fact that for some reason, the Canvas where you do
> the create_image does *not* keep a reference on the actual PhotoImage
> object. So this object disappears when your variable mudPhoto goes out of
> scope (i.e. at the end of your OnClick function), which causes its
> deletion at tk level. So when OnClick finishes, the canvas finds itself
> displaying an image that doesn't exist anymore.
>
> The workaround is simple: always keep an explicit reference on all your
> PhotoImage and BitmapImage objects until you no more need them. For your
> particular case, this can be done via:
>
> def OnClick(event):
> print "click!!!"
> c.create_rectangle(10,10,50,50)
> c.mudPhoto = PhotoImage(file="/root/metropolis/mud.gif")
> c.create_image(50, 50, anchor=NW, image=c.mudPhoto)
>
> Turning mudPhoto into an attribute of the canvas ensures that it won't be
> deleted before the canvas is.
>
> HTH
More information about the Python-list
mailing list