Tkinter Treeview:拦截节点选中同时保留默认批量选择功能
Tkinter Treeview 选择逻辑问题
在Tkinter的Treeview组件中,展开或折叠父节点时,父节点会像子条目一样被选中/取消选中,这不符合业务需求。自定义选择处理器并绑定到ButtonRelease-1事件后,Shift-click批量选择功能失效。希望仅拦截父节点的选中操作,其他选择场景保留默认处理器逻辑以恢复批量选择,无需重新实现该功能。尝试通过bind()获取默认回调未成功,还尝试绑定<<TreeviewOpen>>/<<TreeviewClose>>事件移除选中,但出现节点折叠时选中状态被意外清除的问题。
代码示例1:自定义ButtonRelease事件处理器
import tkinter as tk from tkinter.ttk import * class TV: # 可以起个更合适的名字 def __init__(self, window): self.tree = Treeview(window, selectmode="none", show="tree") self.tree.pack(expan=1,fill='both') self.tree.bind("<ButtonRelease-1>", self.treeSelect) # 问题:如何获取默认处理器? # 生成测试数据 parents = ['1', '2', '3'] children = ['a', 'b', 'c'] for parent in parents: self.tree.insert('', tk.END, iid=parent, text=parent) for child in children: # 插入子项 self.tree.insert(parent, tk.END, iid=parent+':'+child, text=child) # 私有/保护方法 def treeSelect(self, event): curItem = self.tree.focus() # 获取当前聚焦的项 # 如果项没有子节点(即不是父节点) if(not len(self.tree.get_children(curItem))): # 执行选择操作 self.tree.selection_toggle(curItem) # 问题:如何调用默认处理器? # 创建窗口 window = tk.Tk() window.title("test") tv = TV(window) window.mainloop()
代码示例2:绑定展开/折叠事件移除选中
import tkinter as tk from tkinter.ttk import * class TV: # 可以起个更合适的名字 def __init__(self, window): self.tree = Treeview(window, show="tree") self.tree.pack(expan=1,fill='both') self.tree.bind("<<TreeviewOpen>>", self.treeOpenCloseUnselect, '+') self.tree.bind("<<TreeviewClose>>", self.treeOpenCloseUnselect, '+') # 生成测试数据 parents = ['1', '2', '3'] children = ['a', 'b', 'c'] for parent in parents: self.tree.insert('', tk.END, iid=parent, text=parent) for child in children: # 插入子项 self.tree.insert(parent, tk.END, iid=parent+':'+child, text=child) # 私有/保护方法 def treeOpenCloseUnselect(self, event=None): curItem = self.tree.focus() # 获取当前聚焦的项 # 原代码注释与逻辑不符:此处实际移除了所有触发展开/折叠事件的项的选中状态 self.tree.selection_remove(curItem) # 创建窗口 window = tk.Tk() window.title("test") tv = TV(window) window.mainloop()
内容的提问来源于stack exchange,提问作者Mister Mystère
相关产品推荐
相关产品推荐

