Tkinter中选中TreeView条目时如何显示JSON内图片路径对应的图片
实现TreeView选中条目时在Label显示对应图片
问题说明
用Tkinter的TreeView展示JSON中的客户数据,JSON包含图片存储路径。目前选中TreeView条目时仅显示图片路径,直接加载路径能正常显示图片,但不知道如何在选中条目时直接在Label中显示对应图片。
解决方案
要实现这个功能,需要借助PIL(Pillow库)来加载并处理图片,然后在选中条目时将图片设置到指定的Label组件中。具体步骤如下:
- 安装Pillow库(如果未安装):
pip install pillow - 在代码中添加用于显示图片的Label组件
- 修改
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()
关键修改说明
- 引入Pillow库:使用
Image和ImageTk模块处理图片,将本地图片转换为Tkinter支持的格式 - 新增图片显示Label:在界面右侧添加了一个蓝色Frame,内部放置用于显示图片的Label
- 修改
select_record函数:- 获取选中条目的图片路径
- 用
Image.open加载图片,通过thumbnail按比例缩放以适配Label尺寸 - 将图片转换为
PhotoImage并设置到Label中,同时保存图片引用防止被垃圾回收 - 添加异常处理,图片加载失败时显示错误提示
- 修改
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
相关产品推荐
相关产品推荐

