Python Tkinter PhotoImage

class, python, tkinter

Solution

It does not matter much where you declare the image, as long as

- you create it after initializing `Tk()` (the problem in your first approach)

- the image is in the variable scope when you are using it (the problem in your second approach)

- the image object does not get garbage-collected (another common pitfall)

If you define the image in your `main()` method, then you will have to make it `global`

class MyCustomWindow(Tkinter.Frame):
    def __init__(self, parent):
        Tkinter.Frame.__init__(self, parent)
        Tkinter.Label(self, image=image).pack()
        self.pack(side='top')

def main():
    root = Tkinter.Tk()
    global image # make image known in global scope
    image = Tkinter.PhotoImage(file='image.gif')
    MyCustomWindow(root)
    root.mainloop()

if __name__ == "__main__":
    main()

Alternatively, you could drop your `main()` method entirely, making it global automatically:

class MyCustomWindow(Tkinter.Frame):
    # same as above

root = Tkinter.Tk()
image = Tkinter.PhotoImage(file='image.gif')
MyCustomWindow(root)
root.mainloop()

Or, declare the image in your `__init__` method, but make sure to use the `self` keyword to bind it to your `Frame` object so it is not garbage collected when `__init__` finishes:

class MyCustomWindow(Tkinter.Frame):
    def __init__(self, parent):
        Tkinter.Frame.__init__(self, parent)
        self.image = Tkinter.PhotoImage(file='image.gif')
        Tkinter.Label(self, image=self.image).pack()
        self.pack(side='top')

def main():
    # same as above, but without creating the image

Problem

This is the format of code I currently have: ``` import Tkinter as tk class mycustomwidow: def __init__(self,parent,......) ...... ...... tk.Label(parent,image=Myimage) tk.pack(side='top') def main(): root=tk.Tk() mycustomwindow(root) root.mainlopp() if __name__ == '__main__': main() ``` My problem is: Where should I declare the photo `Myimage` that I used in my class `mycustomwindow`? If I put `Myimage=tk.PhotoImage(data='....')` before the `root=tk.Tk()` like below, it will give me the `too early to create image` error as we can't create an image before the root window. ``` import Tkinter as tk Myimage=tk.PhotoImage(data='....') class mycustomwidow: def __init__(self,parent,......) ...... ...... tk.Label(parent,image=Myimage) tk.pack(side='top') def main(): root=tk.Tk() mycustomwindow(root) root.mainlopp() if __name__ == '__main__': main() ``` If I put `Myimage=tk.PhotoImage(data='....')` in the function `main()` like this, it says it can't find the image `Myimage` in `class mycustomwindow`. ``` import Tkinter as tk class mycustomwidow: def __init__(self,parent,......) ...... ...... tk.Label(parent,image=Myimage) tk.pack(side='top') def main(): root=tk.Tk() Myimage=tk.PhotoImage(data='....') mycustomwindow(root) root.mainlopp() if __name__ == '__main__': main() ``` Is there anything badly wrong with my code structure? Where should I declare `Myimage` so that it can be used in `class mycustomwindow`?

Original source