lads lads - 1 year ago 160
Python Question

How can I periodically change a tkinter image?

I have an image that is saved in a file

and this file is overwritten 2 times per second

(I want to show 2 images per second).

Here is what I have so far:

import tkinter as tk
from PIL import Image, ImageTk

root = tk.Tk()
img_path = 'test.bmp'
img = ImageTk.PhotoImage(, Image.ANTIALIAS))

canvas = tk.Canvas(root, height=400, width=400)
canvas.create_image(200, 200, image=img)


But I don't know how can I refresh the image every ½ second?

I'm using Python3 and Tkinter.

Answer Source

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 be created (and the image object id 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

def update_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

def refresh_image(canvas, img, image_path, image_id):
        pil_img =,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
while not os.path.exists(image_path):  # let it run until image file exists

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)

refresh_image(canvas, img, image_path, image_id)
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download