简体   繁体   English

ttk.treeview selection_set 设置为具有特定 ID 的项目

[英]ttk.treeview selection_set to the item with specific id

I want to edit an item in treeview by another Toplevel window and after editing want to refresh / reload items into list from database and set focus to the edited item.我想通过另一个顶级 window 编辑 treeview 中的一个项目,并且在编辑后希望将项目从数据库刷新/重新加载到列表中并将焦点设置为已编辑的项目。 The problem I am facing is to SET FOCUS TO THE EDITED ITEM IN TREEVIEW.我面临的问题是将焦点设置为 TREEVIEW 中的已编辑项目。 Any help will be appreciated.任何帮助将不胜感激。 Here is the minimal sample code.这是最小的示例代码。

    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

You don't need to delete the existing values in order to update the value.您无需删除现有值即可更新值。 You can simply use the set() method to update your treeview.您可以简单地使用set()方法来更新您的 treeview。

syntax:句法:

tree.set(iid, column=None, value=None) tree.set(iid,列=无,值=无)

If you specify only iid in set method it will return items as dict.如果您在set方法中仅指定 iid,它将以 dict 形式返回项目。

Here is a better way to do the same.这是一个更好的方法来做同样的事情。

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() 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM