Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Tkinter not changing image on button press

I have loaded an image to tkinter label and that image is diplayed in that label.When i press the button i need to change that image.When the button is pressed older image is gone but the new image is not displayed My code is

import Tkinter as tk
from PIL import Image, ImageTk
root = tk.Tk()

def change_pic(labelname):
 photo1 = ImageTk.PhotoImage(Image.open("demo.jpg"))
 labelname.configure(image=photo1)
 print "updated"

vlabel=tk.Label(root)
photo = ImageTk.PhotoImage(Image.open('cardframe.jpg'))
vlabel.configure(image=photo)
vlabel.pack()
b2=tk.Button(root,text="Capture",command=lambda:change_pic(vlabel))
b2.pack()
root.mainloop()
like image 742
Emmanu Avatar asked Jan 15 '17 03:01

Emmanu


2 Answers

In def change_pic(labelname), you need to add labelname.photo = photo1 to make sure photo1 not being garbage collected.

def change_pic(labelname):
    photo1 = ImageTk.PhotoImage(Image.open("demo.jpg"))
    labelname.configure(image=photo1)
    labelname.photo = photo1
    print "updated"

P.S. Looks like both labelname.photo = photo1 and labelname.image = photo1 work.

Check this out for more details: http://effbot.org/tkinterbook/label.htm

You can use the label to display PhotoImage and BitmapImage objects. When doing this, make sure you keep a reference to the image object, to prevent it from being garbage collected by Python’s memory allocator. You can use a global variable or an instance attribute, or easier, just add an attribute to the widget instance.

like image 77
Shane Avatar answered Oct 22 '22 03:10

Shane


The following edits were made:

  1. I have organised your code layout and simplified its syntax where possible. These are to make your code easier to read.
  2. Commonly we make the PIL objects a subset/children of tk. So long it is a part of root (i.e. it is a child of the root or any of its child widgets), your PIL objects will work.

Your working code is shown below:

import Tkinter as tk
from PIL import Image, ImageTk

def change_pic():
    vlabel.configure(image=root.photo1)
    print "updated"

root = tk.Tk()

photo = 'cardframe.jpg'
photo1 = "demo.jpg"
root.photo = ImageTk.PhotoImage(Image.open(photo))
root.photo1 = ImageTk.PhotoImage(Image.open(photo1))

vlabel=tk.Label(root,image=root.photo)
vlabel.pack()

b2=tk.Button(root,text="Capture",command=change_pic)
b2.pack()

root.mainloop()
like image 42
Sun Bear Avatar answered Oct 22 '22 02:10

Sun Bear