6

I am trying to add a PhotoImage() in one of my Frame-widgets. There seem to be a problem though since the graphics of the picture just won't show.

Code below:

        from urllib import urlopen
    import Tkinter
    from Tkinter import *

    class frames(object):

        pictures = {"path": "c:/users/xxxxx/desktop/source/pics/",
                    'google': 'google.gif',
                    'wiki': 'wikipedia.gif',
                    'tyda': 'tyda.gif',
                    "hitta": "hitta.gif"
                    }

        def __init__(self, parent):

            #Creation of main frames
            self.parent = parent
            self.logo_frame = Frame(parent)
            self.input_frame = Frame(parent)
            self.output_frame = Frame(parent)

        def configure(self):
            #root window
            self.parent.geometry('400x400')
            self.parent.title('w0rksuite')
            self.parent.configure(bg='grey')
            ################################################################
            #geometry logo_frame
            self.logo_frame.configure(bg='white', width=385, height=45)
            self.logo_frame.grid(column=0, row=0, padx=6, pady=4)
            ################################################################
            #geometry input_frame
            self.input_frame.configure(bg='white', width=385, height=45)
            self.input_frame.grid(column=0, row=1, padx=6, pady=4)  
            ################################################################
            #geometry output_frame
            self.output_frame.configure(bg='white', width=385, height=280)
            self.output_frame.grid(column=0, row=2, padx=6, pady=4)
            ################################################################

        def frame_objects(self):
            #INPUT ENTRY
            input_entry = Entry(self.input_frame, width=55)
            input_entry.grid(column=0, row=1)
            #INPUT TEXT
            input_text = Label(self.input_frame, text='Search:')
            input_text.grid(column=0, row=0, sticky=W)
            input_button = Button(self.input_frame, text='Find')
            #input_button.configure(height=)
            input_button.grid(column=2, row=1, padx=3, pady=0)
            #IMAGE OBJECTS
            hitta_pic = PhotoImage(file=frames.pictures['path']+frames.pictures['hitta'])
            hitta_button = Button(self.logo_frame, image=hitta_pic)
            hitta_button.grid(column=0, row=0, sticky=W)



#Initiate Windows#############
root = Tk()
master_frames = frames(root)
master_frames.configure()
master_frames.frame_objects()
root.mainloop()
##############################

My bolded text is how I make a PhotoImage and connect it to my frame. The button appears, but there's no graphic for the picture.

If I do this in a separate python-file just to try the functionality, whether or not a button-image can be added to a frame, it works and the picture shows.

Any ideas on why the grapgics won't show?

(Example test where it works): import Tkinter from Tkinter import *

root = Tk()
frame = Frame(root)
image = PhotoImage(file='c:/users/xxxxxxx/desktop/source/pics/hitta.gif')
button = Button(frame, image=image)
button.pack()
frame.pack()
root.mainloop()
skeletonking
  • 63
  • 1
  • 1
  • 5
  • when you are working in a class rather than in global namespace, the picture is stored in a local variable, when the function finishes the local variables are garbage collected, to prevent this you could give your class a list to store images in, then after creating each image do `frames.imagelist.append(image)` and this will keep a reference to each of the images you add to the list – James Kent May 12 '15 at 08:31
  • Possible duplicate of [Cannot Display an Image in Tkinter](https://stackoverflow.com/questions/3359717/cannot-display-an-image-in-tkinter) – Nae Nov 25 '17 at 19:31

1 Answers1

4

Actually, you answered yourself but putting that piece of code at the end of your question to show us where it works:

root = Tk()
frame = Frame(root)
image = PhotoImage(file='c:/users/xxxxxxx/desktop/source/pics/hitta.gif')
button = Button(frame, image=image)
button.pack()
frame.pack()
root.mainloop()

Here the image Object does not get destroyed and stays in memory so you can always reference it and still has its data, but in your frame_objects(self) method of the frames(object) where you created the object :

hitta_pic = PhotoImage(file=frames.pictures['path']+frames.pictures['hitta'])

This object gets destroyed each time you return from frame_objects(self), so you get nothing displayed, One work around is to make this object an attribute of your class frames(object), this way:

self.hitta_pic = PhotoImage(file=frames.pictures['path']+frames.pictures['hitta']) 

But whenever you need to reference this object, you have to do it similar to this:

hitta_button = Button(self.logo_frame, image=self.hitta_pic)#here we associate to the name of object the self keyword.
Iron Fist
  • 10,739
  • 2
  • 18
  • 34
  • Yes ofc!I am new to using classes and wouldn't say I'm a master of how exactly they work and operate just yet.. Thank you for this it gave me a better and deeper insight to how classes operate and work. – skeletonking May 12 '15 at 10:03
  • Sure, just remember this, every method and variable is a class attribute only when referenced with "self" keyword, example: "self.image", If you are happy with the answer, may be you should consider voting it..:) – Iron Fist May 12 '15 at 10:04