Search code examples
pythontkintertreeview

How to make the ttk.Treeview widget not remember the last item that was mouse-clicked or selected?


I notice that after an item in the ttk.Treeview had been selected, even after removing its selection, the ttk.Treeview widget will still remember the last item that was mouse-clicked.

import tkinter as tk
from tkinter import ttk

class App:
    def __init__(self):
        self.root = tk.Tk()
        self.tree = ttk.Treeview(self.root)
        self.tree.pack(side="top", fill="both")
        self.tree.bind("<Leave>", self.remove_selection_appearance)
        for i in range(20):
            self.tree.insert("", "end", text="Item %s" % i)
        self.root.mainloop()

    def remove_selection_appearance(self, event):
        selected_items = event.widget.selection()
        print(f"{selected_items=}")
        event.widget.selection_remove(selected_items)
        # event.widget.selection_toggle(selected_items)
        # event.widget.selection_set("")

if __name__ == "__main__":
    app = App()

Above is a sample code to illustrate this behavior. For example:

  1. When the mouse pointer enters and then leaves the widget, it will print selected_items=().
  2. Next, if Item 3 is clicked on and the mouse pointer then moves out of the widget, the script will print selected_items=('I004',).
  3. Next, by pressing the Shift key and clicking on Item 7 and then moving the mouse pointer out of the widget, the script will print selected_items=('I004', 'I005', 'I006', 'I007', 'I008').
  4. Finally, by pressing the Shift key and clicking on Item 0 and then moving the mouse pointer out of the widget, the script will print selected_items=('I001', 'I002', 'I003', 'I004').

The latter two selections show that group selection started from and ended at 'I004', i.e. Item 3, respectively, despite the .selection_remove() method of the ttk.Treeview widget being used to remove the selections. Also, I had assumed that after removing any selections, the last item that was mouse clicked would similarly be removed/forgotten.

Is there a way to cause the ttk.Treeview widget not to remember the last item that was mouse-clicked? Or is this behaviour baked into the widget?


Solution

  • As far as I can judge, selection is used to highlight items, so using selection_remove your item will still be in focus. If you need to unfocus it, you may use focus(''), though I didn't see any documantation that that is a way to remove focus, but seems to work. So that is how your function can look like:

    def remove_selection_appearance(self, event: tk.Event):
        selected_items = event.widget.selection()
        print(f"{selected_items=}")
        event.widget.selection_remove(selected_items)
        event.widget.focus('')