How can I periodically change a tkinter image?

后端 未结 1 1657
难免孤独
难免孤独 2021-01-21 14:03

I have an image that is saved in a file test.bmp and this file is overwritten 2 times per second
(I want to show 2 images per second).

Here is what I ha

1条回答
  •  爱一瞬间的悲伤
    2021-01-21 14:49

    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
    
    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):
        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()
    while not 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()
    

    0 讨论(0)
提交回复
热议问题