Reputation: 1380
I want to select multiple lines from a ttk.Treeview widget. The minimal code which follows produces this window:
Simply clicking in the window produces correct results. The resulting tree selection is printed when treeview_callback
is called.
However, <Cmd>
clicking which should produce an extended selection does not work but only when the widget is first displayed. The callback function is not called by the virtual event <<TreeviewSelect>>
. <Cmd>
clicking can be made to work by a prior mouse selection without the <Cmd>
key.
The failure is inconsistent. It happens when the treeview is first shown. After a number of <Cmd>
clicks on the same color they start to register. The number of clicks varies but has always been less than twenty. I have not been able to detect any pattern that might explain when it starts working. Once it has started working correctly no relapse into the failure mode has been noticed.
"""Treeview selection error demo."""
import tkinter as tk
import tkinter.ttk as ttk
def treeview_callback(tree: ttk.Treeview):
def print_color_selection(*args):
print(f"{tree.selection()=}")
return print_color_selection
gui = tk.Tk()
tree = ttk.Treeview(gui, columns=('colors',), height=6, selectmode='extended',
show='tree')
tree.grid(column=0, row=0)
tree.tag_bind('colors', '<<TreeviewSelect>>', callback=treeview_callback(tree))
for color in ['blue', 'white', 'red', 'green', 'goldenrod']:
tree.insert('', 'end', color, text=color, tags='colors')
tree.selection_add('white', 'red', 'green')
gui.mainloop()
Upvotes: 0
Views: 433
Reputation: 17008
The workaround I found is to set the focus on the first item before setting the selection:
import tkinter as tk
import tkinter.ttk as ttk
def treeview_callback(tree: ttk.Treeview):
def print_color_selection(*args):
print(f"{tree.selection()}")
return print_color_selection
gui = tk.Tk()
tree = ttk.Treeview(gui, columns=('colors',), height=6, selectmode='extended',
show='tree')
tree.grid(column=0, row=0)
tree.tag_bind('colors', '<<TreeviewSelect>>', callback=treeview_callback(tree))
for color in ['blue', 'white', 'red', 'green', 'goldenrod']:
tree.insert('', 'end', color, text=color, tags='colors')
tree.focus('blue') # <- This gives focus to the first item
tree.selection_set('white', 'red', 'green')
gui.mainloop()
Upvotes: 1