如何在Tkinter中实现TreeView选中项与JSON数据同步更新
解决TreeView更新同步JSON数据的问题
我看你遇到的问题啦:现在点击更新按钮后,TreeView的内容改了,但JSON文件里却多了一条新数据,而不是替换原来的那条。这是因为你在更新JSON的时候用了temp.append(y)——这是往数组里新增元素,不是修改已有元素。
问题根源
你加载TreeView的时候,给每个条目设置的iid正好是JSON数组Example的索引(从0开始的count值),所以我们可以通过选中项的iid直接定位到JSON里要修改的元素位置,然后替换它就行,不用新增。
修改后的update_record函数
def update_record(): selected = json_tree.focus() # 获取选中项的iid,转成整数(对应JSON数组的索引) selected_index = int(selected) # 更新TreeView显示 new_values = (str(logo_lb.get()), str(name_lb.get()), str(lastname_lb.get()), str(something_lb.get())) json_tree.item(selected, text='', values=new_values) # 同步更新JSON文件 with open('prueba1.json', "r") as f: data = json.load(f) # 直接替换对应索引的元素,而不是append data["Example"][selected_index] = { "Logo": new_values[0], "Name": new_values[1], "Last Name": new_values[2], "Something": new_values[3] } with open('prueba1.json', 'w') as f: json.dump(data, f, indent=4) # 清空输入框 logo_lb.delete(0,END) name_lb.delete(0,END) lastname_lb.delete(0,END) something_lb.delete(0,END)
关键修改点
- 拿到选中项的
iid并转成整数selected_index,这个值就是该条目在JSON数组Example里的索引位置。 - 用
data["Example"][selected_index] = 新字典替换掉原来的元素,而不是用append新增。 - 把新值存在
new_values里,避免重复获取输入框内容,代码更简洁。
完整测试代码
如果需要替换整个代码,下面是修改后的完整版本:
import json from tkinter import ttk from tkinter import * import tkinter as tk ventana = tk.Tk() ventana.title("Test") ventana.geometry("1000x600") frame1 = tk.Frame(ventana, bg="green", height=300, width=700) frame1.grid(row=1, column=0) frame2 = tk.Frame(ventana, bg="yellow", height=300, width=700) frame2.grid(row=2, column=0) frame_entry = tk.Frame(frame2) frame_entry.pack(pady=20) tree_frame = tk.Frame(frame1) 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 = Scrollbar(tree_frame) #Frame para el scrollbar del arbol tree_scroll.pack(side=RIGHT, fill=Y) #Lista Treeview json_tree = ttk.Treeview(tree_frame, yscrollcommand=tree_scroll.set) json_tree.pack() #config scroll tree_scroll.config(command=json_tree.yview) json_tree['column'] = ("Logo", "Name", "Last Name", "Something") json_tree.column("#0", width=0, minwidth=0) 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) #headings json_tree.heading("#0", text="", anchor="w") 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") #Open and read json 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 = Label( frame_entry, text="Logo") l1.grid(row=0, column=0) logo_lb = Entry( frame_entry) logo_lb.grid(row=1, column=0) l2 = Label( frame_entry, text="Name") l2.grid(row=0, column=1) name_lb = Entry(frame_entry) name_lb.grid(row=1, column=1) l3 = Label( frame_entry, text="Last Name") l3.grid(row=0, column=2) lastname_lb = Entry(frame_entry) lastname_lb.grid(row=1, column=2) l4 = Label( frame_entry, text="Something") l4.grid(row=0, column=3,) something_lb = Entry(frame_entry) something_lb.grid(row=1, column=3) def select_record(): logo_lb.delete(0,END) name_lb.delete(0,END) lastname_lb.delete(0,END) something_lb.delete(0,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]) select_btn = tk.Button(frame2, text="Select", command=select_record) select_btn.pack(side=LEFT, ipadx=30,) def update_record(): selected = json_tree.focus() # 获取选中项的iid,转成整数(对应JSON数组的索引) selected_index = int(selected) # 更新TreeView显示 new_values = (str(logo_lb.get()), str(name_lb.get()), str(lastname_lb.get()), str(something_lb.get())) json_tree.item(selected, text='', values=new_values) # 同步更新JSON文件 with open('prueba1.json', "r") as f: data = json.load(f) # 直接替换对应索引的元素,而不是append data["Example"][selected_index] = { "Logo": new_values[0], "Name": new_values[1], "Last Name": new_values[2], "Something": new_values[3] } with open('prueba1.json', 'w') as f: json.dump(data, f, indent=4) # 清空输入框 logo_lb.delete(0,END) name_lb.delete(0,END) lastname_lb.delete(0,END) something_lb.delete(0,END) update_btn = tk.Button(frame2, text="Update", command=update_record) update_btn.pack(side=RIGHT,ipadx=30, pady=10) ventana.mainloop()
现在点击更新按钮,TreeView的修改就会同步替换JSON里对应的元素,不会再新增数据啦!
内容的提问来源于stack exchange,提问作者Avada Kedavra
相关产品推荐
相关产品推荐

