lemi57ssss
lemi57ssss

Reputation: 1380

Ttk.Treeview multiple selection fails when some lines are preselected

I want to select multiple lines from a ttk.Treeview widget. The minimal code which follows produces this window:

ttk.Treeview screenshot

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

Answers (1)

Jacques Gaudin
Jacques Gaudin

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

Related Questions