Ayush Mishra
Ayush Mishra

Reputation: 19

How to insert an image using Canvas in Tkinter?

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.

Upvotes: 2

Views: 16174

Answers (3)

Jessica Young
Jessica Young

Reputation: 33

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!

Upvotes: 0

Peter Nazarenko
Peter Nazarenko

Reputation: 411

  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)

Upvotes: 1

Will Keeling
Will Keeling

Reputation: 22994

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()

Upvotes: 11

Related Questions