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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 16:10:27