ttk.treeview selection_set 到具有特定 id 的项目

ttk.treeview selection_set to the item with specific id

我想通过另一个 Toplevel window 编辑 treeview 中的项目,编辑后想刷新/重新加载项目到数据库列表中,并将焦点设置到编辑的项目。 我面临的问题是将焦点设置到 TREEVIEW 中的已编辑项目。任何帮助将不胜感激。 这是最小的示例代码。

    import tkinter as tk
    from tkinter import ttk

    class _tree(tk.Frame):
        def __init__(self, *args):
            tk.Frame.__init__(self, *args)
            self.tree = ttk.Treeview(self, columns = ("id", "name"))
            self.tree.heading("#0", text = "s.n")
            self.tree.heading("#1", text = "id")
            self.tree.heading("#2", text = "name")
            self.tree.pack()
            _items = [[52,"orange"],[61,"manggo"],[1437,"apple"]] # item with id 61 needs to be changed
            sn = 1
            for r in (_items):
                self.tree.insert("", "end", text = str(sn), values = (r[0], r[1]))
                sn += 1
            self.tree.bind("<Double-Button-1>", self._item)

        def _item(self, event):
            global item_values
            global item_id
            global item_name
            idx = self.tree.selection()
            item_values = self.tree.item(idx)
            print("item_values : %s" % item_values)
            item_id = self.tree.set(idx, "#1")
            item_name = self.tree.set(idx, "#2")
            edit_item(self)
    class edit_item(tk.Toplevel):
        def __init__(self, master, *args):
            tk.Toplevel.__init__(self, master)
            self.master = master
            global item_values
            global item_name
            lbl1 = tk.Label(self, text = "item name")
            self.ent1 = tk.Entry(self)
            btn1 = tk.Button(self, text = "update", command = self.update_item)
            lbl1.place(x=0, y=10)
            self.ent1.place(x=90, y=10)
            btn1.place(x=90, y=100)
            self.ent1.insert(0, item_name)
        def update_item(self):
            for i in self.master.tree.get_children():
                self.master.tree.delete(i)
            new_data = [[52,"orange"],[61,"mango"],[1437,"apple"]] # item with id 61 has been changed
            sn = 1
            for r in (new_data):
                self.master.tree.insert("", "end", text = str(sn), values = (r[0], r[1]))
                sn += 1
            # Need to set focus on item with id 61 
            idx = self.master.tree.get_children(item_values['values'][0]) # HERE  NEED  HELP
            self.master.tree.focus_set()
            self.master.tree.selection_set(idx)
            self.master.tree.focus(idx)
            self.destroy()
    def main():
        root = tk.Tk()
        app = _tree()
        app.pack()
        root.mainloop()
if __name__ == "__main__":
    main()

`

I am receiving the following error:
Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.8/tkinter/__init__.py", line 1883, in __call__
    return self.func(*args)
  File "test_tree.py", line 55, in update_item
    idx = self.master.tree.get_children(item_values['values'][0]) # HERE  NEED  HELP
  File "/usr/lib/python3.8/tkinter/ttk.py", line 1225, in get_children
    self.tk.call(self._w, "children", item or '') or ())
_tkinter.TclError: Item 61 not found

您不需要为了更新值而删除现有值。您可以简单地使用 set() 方法来更新您的树视图。

语法:

tree.set(iid, column=None, value=None)

如果您在 set 方法中仅指定 iid,它将 return 项作为字典。

这是一种更好的方法。

from tkinter import ttk 
import tkinter as tk 

titles={'Id': [1,2,3,4,5, 6, 7, 8, 9], 'Names':['Tom', 'Rob', 'Tim', 'Jim', 'Kim', 'Kim', 'Kim', 'Kim', 'Kim']}

def update(selected_index_iid, changed):
    index = treev.index(selected_index_iid)# or just index = treev.index(treev.selection())

    treev.set(selected_index_iid, 1, changed) # updating the tree
    titles['Names'][index] = changed  #updating the dictionary
    print(titles)

def clicked(event):
    global titles
    top = tk.Toplevel(window)

    label = tk.Label(top, text='Update: ')
    label.pack()

    entry = tk.Entry(top)
    entry.insert(0, treev.set(treev.selection())['1']) #if you only specify the iid 'set' will return dict of items, ['1'] is to select 1st column
    entry.pack()

    button= tk.Button(top, text='Update', command=lambda :update(treev.selection(), entry.get()))
    button.pack()
    
    
  
window = tk.Tk() 

treev = ttk.Treeview(window, selectmode ='browse')
treev.bind('<Double-Button-1>', clicked)

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"] = list(x for x in range(len(list(titles.keys()))))
treev['show'] = 'headings'

  
for x, y in enumerate(titles.keys()):
    treev.column(x, minwidth=20, stretch=True,  anchor='c')
    treev.heading(x, text=y)

for args in zip(*list(titles.values())):
    treev.insert("", 'end', values =args) 

window.mainloop()