2

I am trying to insert an image in my python application using Canvas in tkinter. The code for the same is:

class Welcomepage(tk.Frame):

def __init__(self, parent, controller):
    tk.Frame.__init__(self,parent)
    canvas = tk.Canvas(self, width = 1000, height = 1000, bg = 'blue')
    canvas.pack(expand = tk.YES, fill = tk.BOTH)
    image = tk.PhotoImage(file="ice_mix.gif")
    canvas.create_image(480, 258, image = image, anchor = tk.NW)

The image is getting read from the source but still not getting displayed in the frame.I am new to the GUI programming someone please help me out.

1
  • 1
    Replace image with self.image and image = self.image. Commented Mar 15, 2018 at 21:06

3 Answers 3

11

The likely issue here is that the image is being garbage collected by Python and therefore not being displayed - which is what @nae's comment is suggesting. Attaching it to the self reference will stop it from being garbage collected.

self.image = tk.PhotoImage(file="ice_mix.gif")  # Use self.image
canvas.create_image(480, 258, image = self.image, anchor = tk.NW)

The Tkinter Book on effbot.org explains this:

Note: When a PhotoImage object is garbage-collected by Python (e.g. when you return from a function which stored an image in a local variable), the image is cleared even if it’s being displayed by a Tkinter widget.

To avoid this, the program must keep an extra reference to the image object. A simple way to do this is to assign the image to a widget attribute, like this:

label = Label(image=photo) 
label.image = photo # keep a reference!
label.pack()
Sign up to request clarification or add additional context in comments.

Comments

1
  1. If You still need to use a Canvas instead a Label for image placement inside a function or a method You can use an external link for image, and use a global specificator for this link inside a function.
  2. You may need to use SE anchor, not NW.

This code works successfully (gets an OpenCV image from USB-camera and place it in a Tkinter Canvas):

def singleFrame1():
    global imageTK      # declared previously in global area
    global videoPanel1  # also global declaration (initialized as "None")
    videoCapture=cv2.VideoCapture(0)
    success,frame=videoCapture.read()
    videoCapture.release()
    vHeight=frame.shape[0]
    vWidth=frame.shape[1]
    imageRGB=cv2.cvtColor(frame,cv2.COLOR_BGR2RGB)  # OpenCV RGB-image
    imagePIL=Image.fromarray(imageRGB)              # PIL image
    imageTK=ImageTk.PhotoImage(imagePIL)            # Tkinter PhotoImage
    if videoPanel1 is None:
        videoPanel1=Canvas(root,height=vHeight,width=vWidth)  # root - a main Tkinter object
        videoPanel1.create_image(vWidth,vHeight,image=imageTK,anchor=SE)
        videoPanel1.pack()
    else:
        videoPanel1.create_image(vWidth,vHeight,image=imageTK,anchor=SE)

Comments

0

About

Seems like a program that showcase a GIF. I think it is better to "fix" the code for you including step by step tutorial since you look like a beginner.

Fix

Okay, so here is your code.

class Welcomepage(tk.Frame):

def __init__(self, parent, controller):
    tk.Frame.__init__(self,parent)
    canvas = tk.Canvas(self, width = 1000, height = 1000, bg = 'blue')
    canvas.pack(expand = tk.YES, fill = tk.BOTH)
    image = tk.PhotoImage(file="ice_mix.gif")
    canvas.create_image(480, 258, image = image, anchor = tk.NW)

First of all, you never noticed the fact that you didn't add pass to the first class.

class Welcomepage(tk.Frame):
    pass

def __init__(self, parent, controller):
    tk.Frame.__init__(self,parent)
    canvas = tk.Canvas(self, width = 1000, height = 1000, bg = 'blue')
    canvas.pack(expand = tk.YES, fill = tk.BOTH)
    image = tk.PhotoImage(file="ice_mix.gif")
    canvas.create_image(480, 258, image = image, anchor = tk.NW)

The second fact is that since you used the double quote you should be keep using them, because then you can be a great developer. I experienced such a mess as a Python stack dev :(

class Welcomepage(tk.Frame):
    pass
def __init__(self, parent, controller):
    tk.Frame.__init__(self,parent)
    canvas = tk.Canvas(self, width = 1000, height = 1000, bg = "blue")
    canvas.pack(expand = tk.YES, fill = tk.BOTH)
    image = tk.PhotoImage(file="ice_mix.gif")
    canvas.create_image(480, 258, image = image, anchor = tk.NW)

And try using the following code for your line 8~9.

self.image = tk.PhotoImage(file="ice_mix.gif")
canvas.create_image(480, 258, image = self.image, anchor = tk.NW)

I've also noticed that instead of your space, it is supposed to be this.

class Welcomepage(tk.Frame):
    pass
    def __init__(self, parent, controller):
        tk.Frame.__init__(self,parent)
        canvas = tk.Canvas(self, width = 1000, height = 1000, bg = "blue")
        canvas.pack(expand = tk.YES, fill = tk.BOTH)
        self.image = tk.PhotoImage(file="ice_mix.gif")
        canvas.create_image(480, 258, image = image, anchor = tk.NW)

Hope you enjoyed and have a nice day!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.