You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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()

关键修改点说明

  1. 修正列表长度不匹配:补全了Names列表的第9个元素,避免循环时出现索引越界错误。
  2. 保留图片引用:用image_references列表保存所有Label和PhotoImage对象,同时给每个Label绑定image属性,防止Python垃圾回收机制销毁图片。
  3. Label定位到单元格:通过treev.bbox(item_id, column)获取对应单元格的坐标和尺寸,使用place()方法将Label放置到单元格内,并绑定<Configure>事件,在Treeview尺寸变化或滚动时自动更新Label位置。
  4. 图片尺寸适配:用PIL的resize()方法将图片调整为略小于列宽的尺寸,避免超出单元格范围。

内容的提问来源于stack exchange,提问作者bedipat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 23:55:22