FAQ
Hello,
I'm a newbie to Python (literally, within the last two weeks), and I am
playing around with Tkinter to build some simple GUIs. I am attempting
to build a simple class that displays a GIF. Here is the code:

#start of code
from Tkinter import *

class DisplayPict(Frame):

def __init__(self,parent=None):
Frame.__init__(self,parent)
self.pack()
self.img=PhotoImage(file="moon.gif")
self.can=Canvas(self)
self.can.create_image(2,2,image=self.img,anchor=NW)
self.can.pack(fill=BOTH)

#keep a reference to the img around
self.can.photo=self.img

if __name__ == '__main__': DisplayPict().mainloop()
#end of code

Anyway, I started with this code in Windoze using IDLE, and everytime I
ran it I kept getting an empty frame (well, presumably with a Canvas
that had nothing in it). I kept thinking that it had to be something
to do with the whole images-get-garbage-collected-if-not-referenced
issue that I read so much about. So I tried a bunch of different
permutations and nothing made a difference.

On a whim, I tried this code under Linux, and amazingly, it worked just
fine: the image was displayed as expected.

So...I am confused. I tried to do my homework (i.e., read through
"Programming Python", "Learning Python", and scouring the internet),
but I can't come up with an explanation as to why this doesn't work
under Windoze. Can anyone out there show me the error in what I have?

Thanks in advance,
John O

Search Discussions

  • James Stroud at Feb 10, 2006 at 2:01 am

    john.orlando at gmail.com wrote:
    Hello,
    I'm a newbie to Python (literally, within the last two weeks), and I am
    playing around with Tkinter to build some simple GUIs. I am attempting
    to build a simple class that displays a GIF. Here is the code:

    #start of code
    from Tkinter import *

    class DisplayPict(Frame):

    def __init__(self,parent=None):
    Frame.__init__(self,parent)
    self.pack()
    self.img=PhotoImage(file="moon.gif")
    self.can=Canvas(self)
    self.can.create_image(2,2,image=self.img,anchor=NW)
    self.can.pack(fill=BOTH)

    #keep a reference to the img around
    self.can.photo=self.img

    if __name__ == '__main__': DisplayPict().mainloop()
    #end of code

    Anyway, I started with this code in Windoze using IDLE, and everytime I
    ran it I kept getting an empty frame (well, presumably with a Canvas
    that had nothing in it). I kept thinking that it had to be something
    to do with the whole images-get-garbage-collected-if-not-referenced
    issue that I read so much about. So I tried a bunch of different
    permutations and nothing made a difference.

    On a whim, I tried this code under Linux, and amazingly, it worked just
    fine: the image was displayed as expected.

    So...I am confused. I tried to do my homework (i.e., read through
    "Programming Python", "Learning Python", and scouring the internet),
    but I can't come up with an explanation as to why this doesn't work
    under Windoze. Can anyone out there show me the error in what I have?

    Thanks in advance,
    John O
    I'm inclined to think that its your python installation. It worked for
    me with both the cygwin python (both in the console and in an xterm) and
    it also worked for me with idle using enthought python. I haven't tried
    the active state python.
  • John Orlando at Feb 10, 2006 at 4:42 am

    I'm inclined to think that its your python installation. It worked for
    me with both the cygwin python (both in the console and in an xterm) and
    it also worked for me with idle using enthought python. I haven't tried
    the active state python.
    Thanks for giving it a shot. I just checked the version of Python I
    was using: 2.3.4 under Linux, and 2.4.2 under Windoze. So there is a
    difference here I guess, though I'd be surprised if it were actually
    any kind of "fix" between the two versions.

    As a side note, under Win, if I don't put the code in a class it seems
    to work fine. In other words:
    #start code
    from Tkinter import *
    win = Tk()
    img = PhotoImage(file="moon.gif")
    can = Canvas(win)
    can.create_image(2,2,image=img, anchor=NW)

    #no requirement for keeping an instance of the image around here

    win.mainloop()
    #end code

    ...and I get a moon displayed in the top-level window. This got me
    wondering if I was misusing the Frame and/or Canvas widget in some
    fashion (since obviously there is no Frame in the above snippet).

    Any other thoughts out there?

    TIA,
    John
  • James Stroud at Feb 10, 2006 at 5:08 am

    john.orlando at gmail.com wrote:
    I'm inclined to think that its your python installation. It worked for
    me with both the cygwin python (both in the console and in an xterm) and
    it also worked for me with idle using enthought python. I haven't tried
    the active state python.

    Thanks for giving it a shot. I just checked the version of Python I
    was using: 2.3.4 under Linux, and 2.4.2 under Windoze. So there is a
    difference here I guess, though I'd be surprised if it were actually
    any kind of "fix" between the two versions.

    As a side note, under Win, if I don't put the code in a class it seems
    to work fine. In other words:
    #start code
    from Tkinter import *
    win = Tk()
    img = PhotoImage(file="moon.gif")
    can = Canvas(win)
    can.create_image(2,2,image=img, anchor=NW)

    #no requirement for keeping an instance of the image around here

    win.mainloop()
    #end code

    ...and I get a moon displayed in the top-level window. This got me
    wondering if I was misusing the Frame and/or Canvas widget in some
    fashion (since obviously there is no Frame in the above snippet).

    Any other thoughts out there?

    TIA,
    John
    There is a difference between the above code and your prior code, namely
    in that you have explicitly instantiated Tk and put your canvas into the
    "root" toplevel. Try this in idle where it was failing:


    #start of code
    from Tkinter import *

    class DisplayPict(Frame):

    def __init__(self,parent=None):
    Frame.__init__(self,parent)
    self.pack()
    self.img=PhotoImage(file="moon.gif")
    self.can=Canvas(self)
    self.can.create_image(2,2,image=self.img,anchor=NW)
    self.can.pack(fill=BOTH)

    #keep a reference to the img around
    self.can.photo=self.img

    if __name__ == '__main__':

    tk = Tk()
    DisplayPict(tk).mainloop()

    #end of code

    James
  • John Orlando at Feb 10, 2006 at 4:34 pm

    There is a difference between the above code and your prior code, namely
    in that you have explicitly instantiated Tk and put your canvas into the
    "root" toplevel. Try this in idle where it was failing:
    <snip>

    Problem solved...I tried James' suggestion (explicitly instantiating
    the root Tk window, and then running the mainloop() as suggested), but
    it produced the same result i.e. no photo. Ugghhhh...

    I then looked REALLY closely at my code and noticed that my __init__
    function was actually ___init___ (3 underscores instead of 2). Thus, a
    Frame object was being built, but the __init__ function wasn't getting
    run. So no image was ever getting added. Silly underscores...or,
    silly Python newbie :-) It now works under both Linux and Windoze
    just fine.

    I would have thought that having no __init__ function would flag an
    error, but I guess this isn't necessary. I thought about grabbing PDB
    to debug, and I bet this would have shown the error immediately (i.e.,
    it would never have called the function). Being a newbie is such a
    joy...

    Thanks for the help,
    John

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppython-list @
categoriespython
postedFeb 10, '06 at 12:26a
activeFeb 10, '06 at 4:34p
posts5
users2
websitepython.org

2 users in discussion

John Orlando: 3 posts James Stroud: 2 posts

People

Translate

site design / logo © 2022 Grokbase