Tkinter: Update image on Canvas with Button click
Example images
Change only once
Create two ImagePhoto
instances
image1 = tk.PhotoImage(file="ball1.gif")
image2 = tk.PhotoImage(file="ball2.gif")
Put first image on Canvas
and keep its ID
(image_id
).
image_id = canvas.create_image(0, 0, anchor='nw', image=image1)
(Normally it would set center of image in position (0,0) but using anchor='nw'
it would set top-left corner of image in position (0,0). nw
means nord west
/top left
corner.)
When you click button then change it to new image
canvas.itemconfig(image_id, image=image2)
Full code
import tkinter as tk
# --- functions ---
def on_click():
# change image on canvas
canvas.itemconfig(image_id, image=image2)
# --- main ---
root = tk.Tk()
# canvas for image
canvas = tk.Canvas(root, width=60, height=60)
canvas.pack()
# button to change image
button = tk.Button(root, text="Change", command=on_click)
button.pack()
# images
image1 = tk.PhotoImage(file="ball1.gif")
image2 = tk.PhotoImage(file="ball2.gif")
# set first image on canvas
image_id = canvas.create_image(0, 0, anchor='nw', image=image1)
root.mainloop()
Change many times - and cicle images
To change many times and change from last to first it is good to keep images on list
images = [
tk.PhotoImage(file="ball1.gif"),
tk.PhotoImage(file="ball2.gif"),
tk.PhotoImage(file="ball3.gif"),
]
and use variable with current displayed image
current_image_number = 0
Using this variable you can set first image
image_id = canvas.create_image(0, 0, anchor='nw', image=images[current_image_number])
and when you click button then you can increate this variable, check if it is not bigger then lenght of list, and use it to replace image
current_image_number += 1
if current_image_number == len(images):
current_image_number = 0
canvas.itemconfig(image_id, image=images[current_image_number])
In function you have to use global
to change external variable
Full code
import tkinter as tk
# --- functions ---
def on_click():
global current_image_number
# next image
current_image_number += 1
# return to first image
if current_image_number == len(images):
current_image_number = 0
# the same using modulo `%`
#current_image_number = (current_image_number+1) % len(images)
# change image on canvas
canvas.itemconfig(image_id, image=images[current_image_number])
# --- main ---
root = tk.Tk()
# canvas for image
canvas = tk.Canvas(root, width=60, height=60)
canvas.pack()
# button to change image
button = tk.Button(root, text="Change", command=on_click)
button.pack()
# images
images = [
tk.PhotoImage(file="ball1.gif"),
tk.PhotoImage(file="ball2.gif"),
tk.PhotoImage(file="ball3.gif"),
]
current_image_number = 0
# set first image on canvas
image_id = canvas.create_image(0, 0, anchor='nw', image=images[current_image_number])
root.mainloop()
Using class
You can do the same with class
and then you don't need global
but you use self.
import tkinter as tk
# --- classes ---
class MainWindow():
def __init__(self):
self.master = tk.Tk()
# canvas for image
self.canvas = tk.Canvas(self.master, width=60, height=60)
self.canvas.pack()
# images
self.images = [
tk.PhotoImage(file="ball1.gif"),
tk.PhotoImage(file="ball2.gif"),
tk.PhotoImage(file="ball3.gif"),
]
self.current_image_number = 0
# set first image on canvas
self.image_on_canvas = self.canvas.create_image(0, 0, anchor='nw', image=self.images[self.current_image_number])
# button to change image
self.button = tk.Button(self.master, text="Change", command=self.on_click)
self.button.pack()
self.master.mainloop()
def on_click(self):
# next image
self.current_image_number += 1
# return to first image
if self.current_image_number == len(self.images):
self.current_image_number = 0
# change image on canvas
self.canvas.itemconfig(self.image_on_canvas, image=self.images[self.current_image_number])
# --- main ---
MainWindow()
Buy a Coffee