无法在 tkinter 的流中显示图像,而是在同一页上打印所有图像

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

使用以下代码,我想在我的项目中显示来自相对路径 .\Datasets\image_datasets\problem_datasets 的图像,我无法使用 tkinter 这样做,而是显示相同的所有图像 UI window,我希望这些图像像视频的帧流一样显示,你能帮我理解为什么我没有得到预期的输出吗?

代码:

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()

几点:

  • 你不需要lab.photo = img
  • 您需要在循环外定义和打包标签,并只覆盖循环内的图像 属性,否则每次迭代都会创建新标签
  • 我建议使用 os.sep 而不是硬编码文件夹分隔符 \ OS-independent
  • 要真正看到过渡,您需要 time.sleep 或类似的
  • 我的示例将冻结 GUI,如果您希望它在启动您的 image-transitions/“视频”后响应,您将必须实施 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()

您在 for 循环的每次迭代中都创建了新标签。相反,您应该在 for 循环之前创建一次标签并在其中更新其图像。

但是在 tkinter 应用程序中不推荐使用循环和 time.sleep(),建议使用 .after() 代替:

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()