Python循环中pack()函数失效:遍历目录图片并在Tkinter GUI中显示仅出现最后一张图的问题
问题分析与解决方案
嘿,我一眼就看出问题所在了——这不是pack()函数的问题,而是Tkinter处理图片引用的特殊机制在搞鬼!
问题根源
当你在循环中创建ImageTk.PhotoImage对象时,虽然把对应的Label添加到了images列表,但每个img = ImageTk.PhotoImage(photo)对象没有被持久化保存。Python的垃圾回收机制会清理掉没有被任何变量引用的对象,循环结束后,除了最后一个img,前面所有的图片对象都被回收了,所以GUI里就只剩最后一张图能显示。
修复方案
我们只需要给每个PhotoImage对象保留一个引用就行,有两种简单的实现方式:
方案1:将图片对象和标签一起存储
把每个Label和对应的PhotoImage以元组形式存入列表,确保图片对象不会被回收:
from tkinter import * from pathlib import Path from PIL import ImageTk, Image root = Tk() images = [] paths = Path("images").glob('**/*.png') for path in paths: photo = Image.open(path) photo.thumbnail((100, 100)) img = ImageTk.PhotoImage(photo) label = Label(image=img) # 同时保存标签和图片对象,维持引用 images.append((label, img)) # 遍历列表,将标签逐个显示 for label, _ in images: label.pack() root.mainloop()
方案2:将图片对象绑定到标签属性
把PhotoImage对象赋值给Label的自定义属性,这样只要标签存在,图片对象就会被保留:
from tkinter import * from pathlib import Path from PIL import ImageTk, Image root = Tk() images = [] paths = Path("images").glob('**/*.png') for path in paths: photo = Image.open(path) photo.thumbnail((100, 100)) img = ImageTk.PhotoImage(photo) label = Label(image=img) # 将图片绑定到标签的属性上,避免被垃圾回收 label.img = img images.append(label) for image in images: image.pack() root.mainloop()
两种方案都能解决你的问题,任选其一就行~
内容的提问来源于stack exchange,提问作者Revan Mardagh
相关产品推荐
相关产品推荐

