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

Tkinter中选中TreeView条目时如何显示JSON内图片路径对应的图片

实现TreeView选中条目时在Label显示对应图片

问题说明

用Tkinter的TreeView展示JSON中的客户数据,JSON包含图片存储路径。目前选中TreeView条目时仅显示图片路径,直接加载路径能正常显示图片,但不知道如何在选中条目时直接在Label中显示对应图片。

解决方案

要实现这个功能,需要借助PIL(Pillow库)来加载并处理图片,然后在选中条目时将图片设置到指定的Label组件中。具体步骤如下:

  1. 安装Pillow库(如果未安装):pip install pillow
  2. 在代码中添加用于显示图片的Label组件
  3. 修改select_record函数,加载选中条目对应的图片并更新到Label中

修改后的完整代码

import json
from tkinter import ttk
import tkinter as tk
from PIL import Image, ImageTk

class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title("Test")
        self.geometry("1000x600")
        try:
            self.iconbitmap("img/favicon.ico")
        except:
            pass  # 避免图标文件不存在导致报错

        # 新增图片显示区域的Frame和Label
        frame_img = tk.Frame(self, bg="blue", height=300, width=300)
        frame_img.grid(row=1, column=1, rowspan=2)
        self.img_label = tk.Label(frame_img, bg="white")
        self.img_label.pack(pady=20, padx=20, fill=tk.BOTH, expand=True)

        frame1 = tk.Frame(self, bg="green", height=300, width=700)
        frame1.grid(row=1, column=0)

        frame2 = tk.Frame(self, bg="yellow", height=300, width=700)
        frame2.grid(row=2, column=0)

        frame_entry = tk.Frame(frame2) #Frame para los entry
        frame_entry.pack(pady=20)

        tree_frame = tk.Frame(frame1) #Frame para el arbol
        tree_frame.pack(pady=20)

        #style del tree
        style = ttk.Style()
        style.theme_use("clam")
        style.configure("Treeview", background="#c7c7c7", foreground="black", rowheight=25,fieldbackground="#a1a1a1")
        style.map("Treeview", background=[('selected','green')])

        tree_scroll = tk.Scrollbar(tree_frame) 
        tree_scroll.pack(side=tk.RIGHT, fill=tk.Y)
       
        json_tree = ttk.Treeview(tree_frame, yscrollcommand=tree_scroll.set)
        json_tree.pack()

        tree_scroll.config(command=json_tree.yview)

        json_tree['column'] = ("Logo", "Name", "Last Name", "Something")

        json_tree.column("#0", width=0, minwidth=0)#Columna Fantasma
        json_tree.column("Logo", anchor="w", width=120)
        json_tree.column("Name", anchor="w", width=120)
        json_tree.column("Last Name", anchor="w", width=120)
        json_tree.column("Something", anchor="w", width=120)

        json_tree.heading("#0", text="", anchor="w")#Columna Fantasma
        json_tree.heading("Logo", text="Logo", anchor="w")
        json_tree.heading("Name", text="Name", anchor="w")
        json_tree.heading("Last Name", text="Last Name", anchor="w")
        json_tree.heading("Something", text="Something", anchor="w")

        #color rows
        json_tree.tag_configure('par', background="#fff")
        json_tree.tag_configure('inpar', background="#d6d6d6")

        with open('prueba1.json', "r") as f:
            data = json.load(f)

            count=0
            for record in data['Example']:
                if count % 2 ==0:
                    json_tree.insert(parent='', index="end", iid=count, text="", values=(record['Logo'],record['Name'],record['Last Name'],record['Something']), tags=('par',))
                else:    
                    json_tree.insert(parent='', index="end", iid=count, text="", values=(record['Logo'],record['Name'],record['Last Name'],record['Something']), tags=('inpar',))

                count+=1

        #entrys
        l1 = tk.Label( frame_entry, text="Logo")
        l1.grid(row=0, column=0)
        logo_lb = tk.Entry( frame_entry)
        logo_lb.grid(row=1, column=0)

        l2 = tk.Label( frame_entry, text="Name")
        l2.grid(row=0, column=1)
        name_lb = tk.Entry(frame_entry)
        name_lb.grid(row=1, column=1)

        l3 = tk.Label( frame_entry, text="Last Name")
        l3.grid(row=0, column=2)
        lastname_lb = tk.Entry(frame_entry)
        lastname_lb.grid(row=1, column=2)

        l4 = tk.Label( frame_entry, text="Something")
        l4.grid(row=0, column=3,)
        something_lb = tk.Entry(frame_entry)
        something_lb.grid(row=1, column=3)

        def select_record():
            #Limpiar las cajas
            logo_lb.delete(0,tk.END) 
            name_lb.delete(0,tk.END)
            lastname_lb.delete(0,tk.END)
            something_lb.delete(0,tk.END)

            selected = json_tree.focus()
            values = json_tree.item(selected,'values') 

            logo_lb.insert(0, values[0]) 
            name_lb.insert(0,values[1])
            lastname_lb.insert(0,values[2])
            something_lb.insert(0,values[3])

            # 加载并显示图片
            img_path = values[0]
            try:
                # 打开图片并调整大小以适应Label
                img = Image.open(img_path)
                # 获取Label的尺寸,按比例缩放图片
                label_width = self.img_label.winfo_width()
                label_height = self.img_label.winfo_height()
                # 避免Label未渲染导致尺寸为0,设置默认尺寸
                if label_width == 0 or label_height ==0:
                    label_width, label_height = 260,260
                img.thumbnail((label_width, label_height))
                # 转换为Tkinter可用的图片格式
                tk_img = ImageTk.PhotoImage(img)
                # 保存引用,防止图片被垃圾回收
                self.img_label.image = tk_img
                # 更新Label的图片
                self.img_label.config(image=tk_img)
            except Exception as e:
                # 图片加载失败时显示提示
                self.img_label.config(image='', text=f"无法加载图片:\n{str(e)}")

        select_btn = tk.Button(frame2, text="Select", command=select_record)
        select_btn.pack(side=tk.LEFT, ipadx=30,)

        def update_record():        
            selected = json_tree.focus()
            json_tree.item(selected, text='', values=(str(logo_lb.get()),str(name_lb.get()),str(lastname_lb.get()),str(something_lb.get()))) #guardar data

            columns = ("Logo", "Name", "Last Name", "Something")
            data = [dict(zip(columns,json_tree.item(iid,"values"))) for iid in json_tree.get_children()]
            with open("prueba1.json", "w") as f:
                json.dump({"Example":data}, f, indent=4)
            
            logo_lb.delete(0,tk.END) 
            name_lb.delete(0,tk.END)
            lastname_lb.delete(0,tk.END)
            something_lb.delete(0,tk.END)
            # 清空图片显示
            self.img_label.config(image='', text='')

        update_btn = tk.Button(frame2, text="Update", command=update_record)
        update_btn.pack(side=tk.RIGHT,ipadx=30, pady=10)

if __name__ == "__main__":
    app = App()
    app.mainloop()

关键修改说明

  1. 引入Pillow库:使用Image和ImageTk模块处理图片,将本地图片转换为Tkinter支持的格式
  2. 新增图片显示Label:在界面右侧添加了一个蓝色Frame,内部放置用于显示图片的Label
  3. 修改select_record函数:
    • 获取选中条目的图片路径
    • 用Image.open加载图片,通过thumbnail按比例缩放以适配Label尺寸
    • 将图片转换为PhotoImage并设置到Label中,同时保存图片引用防止被垃圾回收
    • 添加异常处理,图片加载失败时显示错误提示
  4. 修改update_record函数:更新数据后清空图片显示区域

JSON示例

{
    "Example": [
        {
            "Logo": "C:/Users/*/Desktop/Tkinter/imagel/face1.png",
            "Name": "Charles",
            "Last Name": "Darwin",
            "Something": "4"
        },
        {
            "Logo": "C:/Users/*/Desktop/Tkinter/imagel/face2.png",
            "Name": "Leonardo",
            "Last Name": "Da vinci",
            "Something": "7"
        }
    ]
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 00:52:40