How Can I Periodically Change A Tkinter Image?
Solution 1:
Gee, the code in your question looks very familiar...
Coming up with an answer comprised of tested code was complicated by the need to have the image file be updated by some mysterious unspecified process. This is done in the code below by creating a separate thread that periodically overwrites the image file independent of the main process. I tried to delineate this code from the rest with comments because I felt it was somewhat distracting and makes things seem more complex than they are really.
The main takeaway is that you'll need to use the universal tkinter widget after()
method to schedule the image to be refreshed at some future time. Care also needs to be taken to first create a place-holder canvas image object so it can be updated in-place later. This is needed because there may be other canvas objects present, and otherwise the updated image could cover them up depending on relative placement if a place-holder had not been created (so the image object id that's returned can be saved and used later to change it).
from PIL import Image, ImageTk
import tkinter as tk
#------------------------------------------------------------------------------# Code to simulate background process periodically updating the image file.# Note: # It's important that this code *not* interact directly with tkinter # stuff in the main process since it doesn't support multi-threading.import itertools
import os
import shutil
import threading
import time
defupdate_image_file(dst):
""" Overwrite (or create) destination file by copying successive image
files to the destination path. Runs indefinitely.
"""
TEST_IMAGES = 'test_image1.png', 'test_image2.png', 'test_image3.png'for src in itertools.cycle(TEST_IMAGES):
shutil.copy(src, dst)
time.sleep(.5) # pause between updates#------------------------------------------------------------------------------defrefresh_image(canvas, img, image_path, image_id):
try:
pil_img = Image.open(image_path).resize((400,400), Image.ANTIALIAS)
img = ImageTk.PhotoImage(pil_img)
canvas.itemconfigure(image_id, image=img)
except IOError: # missing or corrupt image file
img = None# repeat every half sec
canvas.after(500, refresh_image, canvas, img, image_path, image_id)
root = tk.Tk()
image_path = 'test.png'#------------------------------------------------------------------------------# More code to simulate background process periodically updating the image file.
th = threading.Thread(target=update_image_file, args=(image_path,))
th.daemon = True# terminates whenever main thread does
th.start()
whilenot os.path.exists(image_path): # let it run until image file exists
time.sleep(.1)
#------------------------------------------------------------------------------
canvas = tk.Canvas(root, height=400, width=400)
img = None# initially only need a canvas image place-holder
image_id = canvas.create_image(200, 200, image=img)
canvas.pack()
refresh_image(canvas, img, image_path, image_id)
root.mainloop()
Post a Comment for "How Can I Periodically Change A Tkinter Image?"