How to update the image of a Tkinter Label widget? - python

I would like to be able to swap out an image on a Tkinter label, but I'm not sure how to do it, except for replacing the widget itself.
Currently, I can display an image like so:
import Tkinter as tk
import ImageTk
root = tk.Tk()
img = ImageTk.PhotoImage(Image.open(path))
panel = tk.Label(root, image = img)
panel.pack(side = "bottom", fill = "both", expand = "yes")
root.mainloop()
However, when the user hits, say the ENTER key, I'd like to change the image.
import Tkinter as tk
import ImageTk
root = tk.Tk()
img = ImageTk.PhotoImage(Image.open(path))
panel = tk.Label(root, image = img)
panel.pack(side = "bottom", fill = "both", expand = "yes")
def callback(e):
# change image
root.bind("<Return>", callback)
root.mainloop()
Is this possible?

The method label.configure does work in panel.configure(image=img).
What I forgot to do was include the panel.image=img, to prevent garbage collection from deleting the image.
The following is the new version:
import Tkinter as tk
import ImageTk
root = tk.Tk()
img = ImageTk.PhotoImage(Image.open(path))
panel = tk.Label(root, image=img)
panel.pack(side="bottom", fill="both", expand="yes")
def callback(e):
img2 = ImageTk.PhotoImage(Image.open(path2))
panel.configure(image=img2)
panel.image = img2
root.bind("<Return>", callback)
root.mainloop()
The original code works because the image is stored in the global variable img.

Another option to do it.
Using object-oriented programming and with an interactive interface to update the image.
from Tkinter import *
import tkFileDialog
from tkFileDialog import askdirectory
from PIL import Image
class GUI(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
w,h = 650, 650
master.minsize(width=w, height=h)
master.maxsize(width=w, height=h)
self.pack()
self.file = Button(self, text='Browse', command=self.choose)
self.choose = Label(self, text="Choose file").pack()
self.image = PhotoImage(file='cualitativa.gif')
self.label = Label(image=self.image)
self.file.pack()
self.label.pack()
def choose(self):
ifile = tkFileDialog.askopenfile(parent=self,mode='rb',title='Choose a file')
path = ifile.name
self.image2 = PhotoImage(file=path)
self.label.configure(image=self.image2)
self.label.image=self.image2
root = Tk()
app = GUI(master=root)
app.mainloop()
root.destroy()
Replace 'cualitativa.jpg' for the default image you want to use.

Another solution that might be of help.
In my case, I had two tk.Tk() windows. When using ImageTk.PhotoImage(), the object defaults to setting its tk window to being the first one created. A simple fix to this is to pass the tk window that you want as such ImageTk.PhotoImage(img, master=your_window)
import tkinter as tk
from PIL import ImageTk, Image
if __name__ == '__main__':
main_window = tk.Tk()
second_window = tk.Tk()
main_canvas = Canvas(second_window)
main_canvas.pack()
filename = 'test.png'
img = Image.open(filename)
img = img.resize((300, 100), Image.ANTIALIAS)
logo = ImageTk.PhotoImage(img, master=second_window)
logo_label = Label(master=main_canvas, image=logo)
logo_label.image = logo
logo_label.pack()
main_window.mainloop()

Related

tkinter puts second frame with toplevel

I'm programing a background to this program and it gives a second frame when I run it. I dont know why this happens but it does. here is the program
import tkinter as tk
import os
from PIL import ImageTk, Image
parent = os.path.dirname(os.path.realpath(__file__))
assets = os.path.join(parent,"assets")
backgrounds = os.path.join(assets,"backgrounds")
print(assets)
root = tk.Toplevel()
frame = tk.Frame(root)
frame.pack()
path = os.path.join(backgrounds,"red to blue.png")
img = ImageTk.PhotoImage(Image.open(path))
panel = tk.Label(root, image=img)
panel.pack(side="bottom", fill="both", expand="yes")
root.mainloop()
Ok so the answer was that I needed it to be tk.Tk() instead of tk.Toplevel() and it works now.

`_tkinter.TclError: image "pyimage1" doesn't exist`

I'm writing a code and I'm getting this error:
this is all the nessacery code
import os
import random
from PIL import ImageTk, Image
import tkinter as tk
def controlmenu():
root = tk.Tk()
frame = tk.Frame(root)
frame.pack()
path = "C:\\Users\user\\Documents\\Codes\\Python\\beathouse\\images\\controllermapping.jpg"
img = ImageTk.PhotoImage(Image.open(path))
panel = tk.Label(root, image=img)
panel.pack(side="bottom", fill="both", expand="yes")
root.mainloop()
root = tk.Tk()
frame = tk.Frame(root)
root.config(bg="black")
root.title("menu")
frame.pack()
bgc = "black"
fgc = "white"
conrtols=tk.Button(frame,
fg=fgc,
bg=bgc,
text="view controls",
command=controlmenu)
conrtols.pack(side=tk.LEFT)
root.mainloop()
and this is the error
this is not the exact code but i tested this exactly and it threw this error
meaning there are the same errors
Credit to Cool Cloud.
So the code says:
root=tk.Tk()
Well it needs to say:
root=tk.TopLevel()

How to create an image button in tkinter? and how to put into another interface?

from tkinter import *
from PIL import ImageTk, Image
root = Tk()
def save():
editor = Tk()
img= Image.open('images/save.png')
fixed= ImageTk.PhotoImage(img)
btn_save_editor = Button(editor, image=fixed)
btn_save_editor.place(x=30, y=80, height=20)
root.mainloop()
From another interface, if you mean another window, then you should use a TopLevel widget, not TK
from tkinter import *
from PIL import ImageTk, Image
root = Tk()
def save():
editor = Toplevel()
editor.geometry("500x500") # you can change it
img = Image.open('images/save.png')
fixed= ImageTk.PhotoImage(img)
btn_save_editor = Button(editor, image=fixed)
btn_save_editor.place(x=30, y=80, height=20)
save()
root.mainloop()

How to change image in a Label in python using tkinter?

I have an image in a label and I want that image to be changed when I press the button but instead of changing the image the window becomes blank:
from tkinter import *
from PIL import Image,ImageTk
import os
root = Tk()
root.state("zoomed")
def chng():
photo2 = ImageTk.PhotoImage(Image.open("upload.jpg"))
img.config(image = photo2)
img.grid()
photo = ImageTk.PhotoImage(Image.open("cat.jpg"))
img = Label(root,image = photo)
upload = Button(root, text= "Upload" ,height = 3, width = 12, command =
chng)
upload.grid( )
for col_num in range(root.grid_size()[1]):
root.columnconfigure(col_num, minsize=600)
for row_num in range(root.grid_size()[1]):
root.rowconfigure(row_num, minsize=60)
img.grid()
root.mainloop()
You have to keep a reference to the image.
def chng():
photo2 = ImageTk.PhotoImage(Image.open("upload.jpg"))
img.config(image = photo2)
img.photo_ref = photo2 # keep a reference
And you don't need the extra grid() call.
Try this:
def chng():
photo2 = ImageTk.PhotoImage(Image.open("upload.jpg"))
img.config(image = photo2)
img.grid()
root.update_idletasks()
import Tkinter as tk
from PIL import Image
class Application(tk.Frame):
def __init__(self, master=None):
tk.Frame.__init__(self, master)
self.grid(row=5,column=2)
self.createWidgets()
top = self.winfo_toplevel()
def createWidgets(self):
self.grid()
app = Application()
simge = tk.PhotoImage(file="bg.png")
hira1 = tk.Label(image=simge)
hira1.grid(row=0,column=0,rowspan=5)
def manu1(event):
simen1=tk.PhotoImage(file="bg1.png")
hira1.configure(image=simen1)
hira1(image=simen1)
hira1.bind("<Button 1>",manu1)
app.mainloop()

Python Tkinter show image acessed on a listbox

I'm trying to make a python script that shows a image that is acessed on a listbox. This code that I got on the internet works:
import Tkinter as tk
from PIL import ImageTk, Image
window = tk.Tk()
path = 'img\\2015722_univ_sqs_sm.jpg'
img = ImageTk.PhotoImage(Image.open(path))
panel = tk.Label(window, image = img)
panel.pack(side = "bottom", fill = "both", expand = "yes")
window.mainloop()
But when I tried to adapt it do the listbox it stopped working.
from Tkinter import *
from PIL import ImageTk, Image
import glob
files = glob.glob('img\\*.jpg')
class App:
def __init__(self, root):
self.l = Listbox(root, width = 50, height = 15)
self.l.pack()
self.l.bind('<<ListboxSelect>>', self.lol)
self.c = Label(root)
self.c.pack()
for f in files:
self.l.insert(END, f)
def lol(self, evt):
path = files[self.l.curselection()[0]]
img = ImageTk.PhotoImage(Image.open(path))
self.c.image = img
self.c.pack()
root = Tk()
App(root)
root.mainloop()
What am I missing?
You must use the configure method of the label, and store a reference to the image somewhere.
self.c.image = img # save reference
self.c.configure(image=img) # configure the label

Categories