Python Forum

Full Version: simple tkinter question function call not opening image
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I had some free time and was messing tkinter again, i wanted to create a function to open a image so that i could simply call the function to get the image but The Image would not appear in the Frame while calling from the function but if ran in multiple lines of code the image appears just fine. i dont see why the function prevents the image from being placed inside the Frame.

from tkinter import *
from PIL import ImageTk,Image


root = Tk()
root.geometry("400x400")


def open_image():
	frame = Frame(root,width=200,height=200,bd=5,bg='white')


	photo = ImageTk.PhotoImage(Image.open('image.jpg'))
	photo_label = Label(image=photo)
	photo_label.pack()

open_image()

root.mainloop()
you need to pass the arguments to the function, like:

def open_image(imagename):
    frame = Frame(root,width=200,height=200,bd=5,bg='white')
 
 
    photo = ImageTk.PhotoImage(Image.open(imagename))
    photo_label = Label(image=photo)
    photo_label.pack()
and then call like:
open_image('image.jpg')

get that to work, and then try creating another function to create the frame ( and return instance)
and then pass that to the open_image(framename, imagename): ...
i tried that and that isn't working either,i wasn't sure if it was the name of the image ,the path or what but i tried both as parameters when calling the function open_image(). but tkinter just opens the geometry window and the blank 200x200 Frame but no image.
i dont see what is going wrong here.
this is where i am grabbing the image: photo = ImageTk.PhotoImage(Image.open(image_name))
this is where i am creating the Label to pack the photo onto : photo_label = Label(image=photo)
then just pack the dang thing to the frame
and call the function with my image..

from tkinter import *
from PIL import ImageTk,Image


root = Tk()
root.geometry("400x400")


def open_image(image_name):
	frame = Frame(root,width=200,height=200,bd=5,bg='white')
	frame.pack(pady=15)


	photo = ImageTk.PhotoImage(Image.open(image_name))
	photo_label = Label(image=photo)
	photo_label.pack()

open_image('babu.jpg')  #the name of the image is babu.jpg 

root.mainloop()
You need to add photo.image = photo after photo = Imagetk.Pho..... The image is getting garbage collected. You need a refernce to it.
That should be photo_label.image = photo. Having photo reference itself might be confusing. I don't know if Python would ever recover the image memory if you switched the label to display a different image. This would result in your program consuming more and more memory each time it opened a new image file. This would be a bad thing for something like a slide viewer.

If this is something you do a lot it might be worth making a class.
class PhotoLabel(tk.Label):
    """ A Label that displays a photo """
    def __init__(self, *args, image_file=None, **kwargs):
        super().__init__(*args, **kwargs)
        self.reference = None
        if image_file is not None:
            self.open(image_file)

    def open(self, image_file):
        """ Load image from file """
        self["image"] = self.reference = ImageTk.PhotoImage(Image.open(image_file))
        

PhotoLabel(root, image_file='babu.jpg').pack()
Return photo to keep a reference to it, or append to a list, which is mutable. Both are illustrated below.

from tkinter import *
from PIL import ImageTk,Image
 
 
root = Tk()
root.geometry("400x400")
photo_list=[] 
 
def open_image():
    frame = Frame(root,width=200,height=200,bd=5,bg='white')
 
 
    photo = ImageTk.PhotoImage(Image.open('image.jpg'))
    photo_label = Label(image=photo)
    photo_label.pack()
 
    photo_list.append(photo)
    return photo

photo=open_image()
 
root.mainloop()