Tkinter TreeView选中项如何取回原类对象而非字符串
解决Tkinter TreeView中取回自定义类对象的问题
TreeView在插入数据时会自动将所有元素转为字符串存储,所以直接存入自定义类对象只会保留其字符串表示,无法直接取回原对象。以下是两种实用的解决方法:
方法一:利用TreeView的set方法绑定额外数据(推荐)
插入行时,将自定义对象绑定到该行的一个虚拟属性上,选中行时直接通过set方法取回原对象。
import tkinter as tk from tkinter import ttk class DataDTO: def __init__(self, id, name, extra_info): self.id = id self.name = name self.extra_info = extra_info def on_list_select(event): selected_items = tree.selection() if selected_items: selected_iid = selected_items[0] # 直接取回绑定的原对象 data_obj = tree.set(selected_iid, "data") print(type(data_obj)) # 输出 <class '__main__.DataDTO'> print(data_obj.extra_info) root = tk.Tk() tree = ttk.Treeview(root, columns=("id", "name")) tree.heading("#0", text="Index") tree.heading("id", text="ID") tree.heading("name", text="Name") tree.pack() # 插入数据并绑定自定义对象 dto1 = DataDTO(1, "Alice", "Extra info for Alice") iid1 = tree.insert("", "end", text="1", values=(dto1.id, dto1.name)) tree.set(iid1, "data", dto1) dto2 = DataDTO(2, "Bob", "Extra info for Bob") iid2 = tree.insert("", "end", text="2", values=(dto2.id, dto2.name)) tree.set(iid2, "data", dto2) tree.bind("<<TreeviewSelect>>", on_list_select) root.mainloop()
方法二:维护iid到对象的字典映射
创建一个字典,将TreeView行的iid作为键,自定义对象作为值存入,选中行时通过iid从字典中取出原对象。
import tkinter as tk from tkinter import ttk class DataDTO: def __init__(self, id, name, extra_info): self.id = id self.name = name self.extra_info = extra_info # 存储行iid到DataDTO对象的映射 item_map = {} def on_list_select(event): selected_items = tree.selection() if selected_items: selected_iid = selected_items[0] data_obj = item_map.get(selected_iid) if data_obj: print(type(data_obj)) # 输出 <class '__main__.DataDTO'> print(data_obj.extra_info) root = tk.Tk() tree = ttk.Treeview(root, columns=("id", "name")) tree.heading("#0", text="Index") tree.heading("id", text="ID") tree.heading("name", text="Name") tree.pack() # 插入数据并建立映射 dto1 = DataDTO(1, "Alice", "Extra info for Alice") iid1 = tree.insert("", "end", text="1", values=(dto1.id, dto1.name)) item_map[iid1] = dto1 dto2 = DataDTO(2, "Bob", "Extra info for Bob") iid2 = tree.insert("", "end", text="2", values=(dto2.id, dto2.name)) item_map[iid2] = dto2 tree.bind("<<TreeviewSelect>>", on_list_select) root.mainloop()
注意事项
- 方法一无需额外维护字典,利用TreeView自身机制实现,更简洁;
- 若使用方法二,当TreeView的行被删除时,需要同步清理字典中的对应条目,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Michelle Nicholes
相关产品推荐
相关产品推荐

