无法在 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()
使用以下代码,我想在我的项目中显示来自相对路径 .\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()