'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()
Solution 1:[1]
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()
Solution 2:[2]
A couple of points:
- you dont need
lab.photo = img - you need to define and pack the label outside of your loop and just overwrite the image property inside, otherwise you create new labels each iteration
- i recommend using
os.sepinstead of hardcoded folder separators\\to be OS-independent - to actually see the transition, you need
time.sleepor similar - my example will freeze the GUI, if you want it to be reactive after launching your image-transitions/"video", you will have to implement Threads
import tkinter as tk
from PIL import ImageTk, Image
from matplotlib import image
from numpy import imag
import matplotlib.pyplot as plt
import glob
import os
import time
root = tk.Tk()
root.title("Test app")
images = [file for file in glob.glob('.' + os.sep + 'Datasets' + os.sep + 'image_datasets' + os.sep + 'problem_datasets' + os.sep + '*.jpg')]
lab = tk.Label(root)
lab.pack()
for path in images:
_img = ImageTk.PhotoImage(Image.open(path))
lab.config(image=_img)
root.update() # to update the GUI
time.sleep(0.25) # to see the transition
root.mainloop()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | acw1668 |
| Solution 2 | mnikley |

