In a Tkinter's treeview, when nodes are expanded and collapsed, the node get selected/deselected just like any child entry. I can't have that for my application, so I made a selection handler and bound it to the ButtonRelease event. The problem is that now, the shift-click bulk selection does not work - simply because I haven't written it in my handler. But it's a pain to write with treeviews, my IIDs are not easily iterable in my implementation.
I would like to intercept the message if the node is selected (which I'm already doing), and call the default handler for any other selection such that I get the shift-click bulk selection feature back without reinventing the wheel. How can I do that?
I've tried looking at the result of bind() with and without the new callback parameter in the hope of storing the default callback/handler, but it did not work so this is a dead-end as far as I know.
import tkinter as tk
from tkinter.ttk import *
class TV: #Find a better name
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) #HERE: how to get the default handler?
#Generate dummy data
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:
#Insert the item
self.tree.insert(parent, tk.END, iid=parent+':'+child, text=child)
#Private/protected methods
def treeSelect(self, event):
curItem = self.tree.focus() #Get selected item by getting the item in focus
#If the item has no children (i.e. it's not a node)
if(not len(self.tree.get_children(curItem))):
#Execute the selection
self.tree.selection_toggle(curItem) #HERE: how to call the default handler?
#Create the window
window = tk.Tk()
window.title("test")
tv = TV(window)
window.mainloop()
I've tried this as well but for some reason Tkinter thinks the selection needs to be cleared when the selected items collapse in their node...
import tkinter as tk
from tkinter.ttk import *
class TV: #Find a better name
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, '+')
#Generate dummy data
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:
#Insert the item
self.tree.insert(parent, tk.END, iid=parent+':'+child, text=child)
#Private/protected methods
def treeOpenCloseUnselect(self, event=None):
curItem = self.tree.focus() #Get selected item by getting the item in focus
#If the item has no children (i.e. it's not a node)
self.tree.selection_remove(curItem)
#Create the window
window = tk.Tk()
window.title("test")
tv = TV(window)
window.mainloop()