[Tkinter-discuss] Extend selection in ttk.Treeview

Vasilis Vlachoudis Vasilis.Vlachoudis at cern.ch
Wed Jan 6 04:57:57 EST 2021


For the moment I came up with this solution, which seems to work,
however I am not very happy with it.
I need to define an "anchor" variable to remember from where the selection started

class MyTreeview(ttk.Treeview):
   def __init__(self, master, *kw, **args):
      super().__init__(master, *kw, **args)
      self.bind("<B1-Motion>", self.b1motion)
      self.bind("<ButtonRelease-1>", self.release)
      self.bind("<Up>",self.up)
      self.bind("<Down>", self.down)
      self.bind("<Shift-Key-Up>", self.selectUp)
      self.bind("<Shift-Key-Down>",self.selectDown)
      self._anchor = ""

   # ----------------------------------------------------------------------
   def b1motion(self, event):
      # If selected item is the last one focused
      # then ignore, otherwise Select is selecting everything
      if self.identify_row(event.y) == self.focus(): return
      self.tk.call("ttk::treeview::Select", self._w, event.x, event.y, "extend")

   # ----------------------------------------------------------------------
   def release(self, event):
      self.tk.call("ttk::treeview::Release", self._w, event.x, event.y)
      self._anchor = self.focus()
      return "break"

   # ----------------------------------------------------------------------
   def up(self, event):
      self.tk.call("ttk::treeview::Keynav", self._w, "up")
      self._anchor = self.focus()
      return "break"

   # ----------------------------------------------------------------------
   def down(self, event):
      self.tk.call("ttk::treeview::Keynav", self._w, "down")
      self._anchor = self.focus()
      return "break"

   # ----------------------------------------------------------------------
   def selectUp(self, event):
      if not self._anchor: self._anchor = self.focus()
      self.tk.call("ttk::treeview::Keynav", self._w, "up")
      if self.focus() != self._anchor:
            self.tk.call("ttk::treeview::SelectOp", self._w, self._anchor, "extend")
      return "break"

   # ----------------------------------------------------------------------
   def selectDown(self, event):
      if not self._anchor: self._anchor = self.focus()
      self.tk.call("ttk::treeview::Keynav", self._w, "down")
      if self.focus() != self._anchor:
            self.tk.call("ttk::treeview::SelectOp", self._w, self._anchor, "extend")
      return "break"

________________________________
From: Tkinter-discuss [tkinter-discuss-bounces+vasilis.vlachoudis=cern.ch at python.org] on behalf of Vasilis Vlachoudis [Vasilis.Vlachoudis at cern.ch]
Sent: Tuesday, January 05, 2021 12:06
To: tkinter-discuss at python.org
Subject: [Tkinter-discuss] Extend selection in ttk.Treeview

Hi all,

I am currently replacing some Listbox() with ttk.Treeview() however the Treeview doesn't have the
"Shift-Up/Down" and "B1-Motion" capabilities to select with the keyboard multiple items and with the mouse by click and drag.

Looking the treeview.tcl I've managed to add a binding for the B1-Motion which seems to work,
however I failed to find a way to correctly replicate the Listbox behavior with the Shift-Up/Down
This is one of my failed tries

Any suggestion?

class MyTreeview(ttk.TreeView):
def __init__(self, master, *kw, **args):
super().__init__(master, *kw, **args)
self.bind("<B1-Motion>", self.b1motion)
self.bind("<Shift-Key-Up>", self.selectUp)
self.bind("<Shift-Key-Down>", self.selectDown)

def b1motion(self, event):
if self.identify_row(event.y) == self.focus(): return
self.tk.call("ttk::treeview::Select", self._w, event.x, event.y, "extend")

def selectDown(self, event):
self.tk.call("ttk::treeview::Keynav", self._w, "down")
item = self.focus()
self.tk.call("ttk::treeview::SelectOp", self._w, item, "extend")
return "break"
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.python.org/pipermail/tkinter-discuss/attachments/20210106/908e8f07/attachment.html>


More information about the Tkinter-discuss mailing list