循环向Grid布局Frame添加图片仅显示在最后一个Frame的问题
问题解决:Grid布局中仅最后一个Frame显示图片
问题原因
Tkinter的ImageTk.PhotoImage对象如果没有被Python代码持有引用,会被垃圾回收机制销毁,导致图片无法显示。你在循环里每次创建img变量时,都会覆盖之前的引用,最终只有最后一个img对象保留了引用,所以只有最后一个Frame里的图片能显示。
修复方案
方案1:将图片对象绑定到Label的属性上
在创建Label后,把img赋值给Label的一个自定义属性,确保保留引用,避免被回收。修改后的循环代码如下:
for tile in frameList: # Adding Image to Frame img = ImageTk.PhotoImage(Image.open(tileList[0].image)) label = ttk.Label(tile, image=img) label.img = img # 关键:保留图片对象的引用 label.grid()
方案2:用列表存储所有图片对象
创建一个列表来保存所有img对象,确保每个图片都有引用不被回收:
img_list = [] # 存储图片对象,防止被垃圾回收 for tile in frameList: img = ImageTk.PhotoImage(Image.open(tileList[0].image)) img_list.append(img) label = ttk.Label(tile, image=img) label.grid()
额外提示:显示不同图片
如果需要每个Frame显示不同图片,可通过索引对应tileList中的元素:
img_list = [] for idx, tile in enumerate(frameList): if idx < len(tileList): img = ImageTk.PhotoImage(Image.open(tileList[idx].image)) img_list.append(img) label = ttk.Label(tile, image=img) label.grid()
完整修复后的代码示例
from tkinter import ttk from PIL import Image, ImageTk # 假设root已初始化,tileList已定义 i = 1 j = 0 frameList = [] while i < 4: while j < 3: frameN = ttk.Frame(root, width=200, height=200, style="tileN.TFrame") frameN.grid(row=i, column=j, padx=1, pady=1, sticky="NEWS") frameN.grid_propagate(False) frameList.append(frameN) j = j + 1 j = 0 i = i + 1 # 修复后的图片添加逻辑 img_list = [] for tile in frameList: img = ImageTk.PhotoImage(Image.open(tileList[0].image)) img_list.append(img) label = ttk.Label(tile, image=img) label.grid()
内容的提问来源于stack exchange,提问作者Kahler Rockwell
相关产品推荐
相关产品推荐

