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()
CodePudding user response:
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()
CodePudding user response:
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.sep
instead of hardcoded folder separators\\
to be OS-independent - to actually see the transition, you need
time.sleep
or 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()