Skip to content

Tkinter ttk.Treeview .selection() gives incorrect result, when crtl+left-click deselecting the last selected item #144439

@ZelphirKaltstahl

Description

@ZelphirKaltstahl

Bug report

Bug description:

My environment is the following:

  • I am using Python 3.13.5
  • on Debian GNU/Linux 13 (trixie)
  • (desktop environment: KDE)
  • tk.TkVersion: 8.6
  • ttk.tkinter.TkVersion: 8.6
  • tk system package:
    $ apt-cache policy tk
    tk:
      Installed: (none)
      Candidate: 8.6.16
      Version table:
         8.6.16 500
            500 http://deb.debian.org/debian trixie/main amd64 Packages
    
  • apt list --installed | grep tk:
    ...
    python3.13-tk/stable,now 3.13.5-2 amd64 [installed,automatic]
    ...
    

What I have observed is, that there seems to be a bug in the method treeview.selection(). Steps to reproduce:

  1. register handlers for "<<TraverseIn>>", something along the lines of:
    def __init__(self ...):
        self.treeview.bind(
            "<<TraverseIn>>",
            self._on_traverse_out_treeview
        )
    ...
    def _on_traverse_out_treeview(self, event: tk.Event) -> str | None:
        logger.info(self.treeview.selection())
  1. start the application
  2. select one item in the treeview using mouse left click
  3. deselect the only one selected item in the treeview, using ctrl + left click
  4. tab through the widgets, until you focus the treeview again
  5. observe how tkinter still logs the deselected item as selected

Workaround

I have found a workaround, which I am currently using.

        # Binding for working around treeview selection bug.
        self.treeview.bind(
            EventName.TRAVERSE_OUT.value,
            self._on_traverse_out_treeview
        )
    ...
    def _on_traverse_out_treeview(self, event: tk.Event) -> None:
        if len(self.treeview.selection()) == 0:
            self.treeview.selection_clear()
            self.treeview.focus("")

This forces the selection and focus to clear, if no item is selected when tabbing out. Then, when tabbing and reaching the treeview again, if there is no visually selected item, the selection state will have been cleared and .selection() will give the correct result.

Side-effects

  • Not yet observed. I only found this workaround today.

CPython versions tested on:

3.13

Operating systems tested on:

Linux

Metadata

Metadata

Assignees

No one assigned

    Labels

    stdlibStandard Library Python modules in the Lib/ directorytopic-tkintertype-bugAn unexpected behavior, bug, or error

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions