Simple Tkinter app works in Linux, not in Windows

J

john.orlando

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
 
J

James Stroud

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.
 
J

john.orlando

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
 
J

James Stroud

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
 
J

john.orlando

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top