如何在Tkinter Treeview中插入列表存储的图片?
解决Treeview单元格显示图片的问题
你的代码核心问题在于Treeview的values参数仅接受可转换为字符串的数据,直接传入Label对象只会显示其内存标识(.!label<数字>)。此外,Tkinter的Treeview本身不支持直接在单元格内嵌入Widget,需要通过「创建Label并定位到对应单元格」的方式实现图片显示,同时要注意保留图片引用防止被垃圾回收。
修改后的完整代码
from tkinter import ttk import tkinter as tk from PIL import Image, ImageTk ID = [1,2,3,4,5, 6, 7, 8, 9] Names = ['Tom', 'Rob', 'Tim', 'Jim', 'Kim', 'Steph', 'Davis', 'Katt', 'Zoe'] # 补全元素避免索引错误 photo = ['1.jpeg', '2.jpeg', '3.jpeg', '4.jpeg', '5.jpeg', '6.jpeg', '7.jpeg', '8.jpeg', '9.jpeg'] window = tk.Tk() window.title("Treeview with Images") treev = ttk.Treeview(window, selectmode='browse') treev.pack(side='left', expand=True, fill='both') verscrlbar = ttk.Scrollbar(window, orient="vertical", command=treev.yview) verscrlbar.pack(side='right', fill='y') treev.configure(yscrollcommand=verscrlbar.set) treev["columns"] = ('1', '2', '3') treev['show'] = 'headings' treev.column("1", width=90, anchor='c') treev.column("2", width=90, anchor='c') treev.column("3", width=90, anchor='c') treev.heading("1", text="ID") treev.heading("2", text="Names") treev.heading("3", text="Photos") # 保存图片和Label引用,防止被垃圾回收 image_references = [] def update_label_positions(event): """Treeview尺寸变化时,更新所有图片Label的位置""" for label, _ in image_references: # 获取对应单元格的坐标和尺寸 bbox = treev.bbox(label.item_id, '3') if bbox: # 确保单元格可见 x, y, width, height = bbox label.place(x=x+2, y=y+2, width=width-4, height=height-4) # 绑定Treeview的配置事件,用于更新Label位置 treev.bind('<Configure>', update_label_positions) # 循环插入数据并创建图片Label for i in range(min(len(ID), len(Names), len(photo))): # 打开并调整图片大小(适配列宽) img = Image.open(photo[i]) img = img.resize((80, 80), Image.Resampling.LANCZOS) tkimage = ImageTk.PhotoImage(img) # 插入Treeview条目,第三列留空 item_id = treev.insert("", 'end', values=(ID[i], Names[i], "")) # 创建显示图片的Label,父组件为Treeview(确保随Treeview滚动) img_label = tk.Label(treev, image=tkimage) img_label.image = tkimage # 保留图片引用 img_label.item_id = item_id # 绑定对应的条目ID,用于定位 image_references.append((img_label, tkimage)) # 初次调用更新位置 update_label_positions(None) window.mainloop()
关键修改点说明
- 修正列表长度不匹配:补全了
Names列表的第9个元素,避免循环时出现索引越界错误。 - 保留图片引用:用
image_references列表保存所有Label和PhotoImage对象,同时给每个Label绑定image属性,防止Python垃圾回收机制销毁图片。 - Label定位到单元格:通过
treev.bbox(item_id, column)获取对应单元格的坐标和尺寸,使用place()方法将Label放置到单元格内,并绑定<Configure>事件,在Treeview尺寸变化或滚动时自动更新Label位置。 - 图片尺寸适配:用PIL的
resize()方法将图片调整为略小于列宽的尺寸,避免超出单元格范围。
内容的提问来源于stack exchange,提问作者bedipat
相关产品推荐
相关产品推荐

