kmote
kmote

Reputation: 16715

Tkinter: Access canvas from button handler

How can I update the canvas from a function called by a button? Here's my code:

from Tkinter import *
import ImageTk

tk = Tk()
canvas = Canvas(tk, bg="white", width=300, height=200)
canvas.grid()

def displayLabel():
    photoimage = ImageTk.PhotoImage(file="Logo.png")
    canvas.create_image(0,0, image=photoimage, anchor = NW)

b3 = Button(tk, text="Display Label", width=30, command= displayLabel())
b3.grid(row=1)

tk.mainloop()

Pressing the "Display Label" button does nothing. I've tried designating the canvas global in the method, or passing the canvas in as an argument (using command = lambda (displayLabel(canvas)), both to no effect. What am I doing wrong?

UPDATE: I now realize my question is a duplicate of this one, but @shalitmaan's answer helped me in ways the other one didn't.

Upvotes: 1

Views: 369

Answers (1)

Alok
Alok

Reputation: 2689

When you add a PhotoImage or other Image object to a Tkinter widget, you must keep your own reference to the image object. If you don’t, the image won’t always show up. Here is essentially what I'm trying to say:

def displayLabel():
    photoimage = ImageTk.PhotoImage(file="lena.png")
    canvas.create_image(0,0, image=photoimage, anchor = NW)
    canvas.image=photoimage #keep the reference!

I learned it from here.

Also you need to remove the parenthesis ()

b3 = Button(tk, text="Display Label", width=30, command= displayLabel) #no parenthesis

otherwise it will be called directly without even the button press. You might not have noticed it up until now since Tk was just making the image blank as you may understand now from the link.

Also if you want to send some arguments to displayLabel you need to use lambda. For eg:

b3 = Button(tk, text="Display Label", width=30, command= lambda:displayLabel(args))

In your asked question,you were missing the colon :

Upvotes: 2

Related Questions