Search code examples
pythonimageuser-interfacetkinterpython-imaging-library

Unable to display images in a stream in tkinter instead it prints all images on same page


With the following code I want to display images from a relative path .\Datasets\image_datasets\problem_datasets within my project, I am unable to do so with tkinter, Instead it displays all the images in same UI window, I want these images to be displayed like a stream of frames as a video, can you help me understand why I don't get the expected ouput.

code :

import tkinter as tk
from PIL import ImageTk, Image
from matplotlib import image
from numpy import imag
import matplotlib.pyplot as plt
import glob

root = tk.Tk()
root.title("Test app")

images = [file for file in glob.glob('.\\Datasets\\image_datasets\\problem_datasets\\*.jpg')]

for path in images:
    img = ImageTk.PhotoImage(Image.open(path))
    lab = tk.Label(root,image=img)
    lab.photo = img
    lab.pack()

root.mainloop()

This is how it get's displayed


Solution

  • You created new label in each iteration of the for loop. Instead you should create the label once before the for loop and update its image inside it.

    However using loop and time.sleep() is not recommended in a tkinter application, suggest to use .after() instead:

    import tkinter as tk
    from PIL import ImageTk, Image
    import glob
    
    root = tk.Tk()
    root.title("Test app")
    
    images = glob.glob('./Datasets/image_datasets/problem_datasets/*.jpg')
    
    # create the label for showing the images
    lab = tk.Label(root)
    lab.pack()
    
    def show_image(i=0):
        if i < len(images):
            img = ImageTk.PhotoImage(file=images[i])
            # update image
            lab.config(image=img)
            lab.photo = img # save reference of image to avoid garbage collection
            # can change 10(ms) to other value to suit your case
            root.after(10, show_image, i+1) 
    
    show_image() # start showing the images
    root.mainloop()