Re: Extend selection in ttk.Treeview
Vasilis Vlachoudis <[email protected]> Wed, 6 Jan 2021 09:57:57 +0000
| Newsgroups | gmane.comp.python.tkinter |
|---|---|
| Message-ID | <[email protected]> |
--===============6332587465758679377==
Content-Language: en-US
Content-Type: multipart/alternative;
boundary="_000_0BC70B5D93E054469872FFD0FE07220E0312E0A6C9CERNXCHG51cer_"
--_000_0BC70B5D93E054469872FFD0FE07220E0312E0A6C9CERNXCHG51cer_
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
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 =3D ""
# ----------------------------------------------------------------------
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) =3D=3D self.focus(): return
self.tk.call("ttk::treeview::Select", self._w, event.x, event.y, "ext=
end")
# ----------------------------------------------------------------------
def release(self, event):
self.tk.call("ttk::treeview::Release", self._w, event.x, event.y)
self._anchor =3D self.focus()
return "break"
# ----------------------------------------------------------------------
def up(self, event):
self.tk.call("ttk::treeview::Keynav", self._w, "up")
self._anchor =3D self.focus()
return "break"
# ----------------------------------------------------------------------
def down(self, event):
self.tk.call("ttk::treeview::Keynav", self._w, "down")
self._anchor =3D self.focus()
return "break"
# ----------------------------------------------------------------------
def selectUp(self, event):
if not self._anchor: self._anchor =3D self.focus()
self.tk.call("ttk::treeview::Keynav", self._w, "up")
if self.focus() !=3D 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 =3D self.focus()
self.tk.call("ttk::treeview::Keynav", self._w, "down")
if self.focus() !=3D self._anchor:
self.tk.call("ttk::treeview::SelectOp", self._w, self._anchor, =
"extend")
return "break"
________________________________
From: Tkinter-discuss [tkinter-discuss-bounces+vasilis.vlachoudis=3Dcern.ch=
@python.org] on behalf of Vasilis Vlachoudis [[email protected]]
Sent: Tuesday, January 05, 2021 12:06
To: [email protected]
Subject: [Tkinter-discuss] Extend selection in ttk.Treeview
Hi all,
I am currently replacing some Listbox() with ttk.Treeview() however the Tre=
eview doesn't have the
"Shift-Up/Down" and "B1-Motion" capabilities to select with the keyboard mu=
ltiple items and with the mouse by click and drag.
Looking the treeview.tcl I've managed to add a binding for the B1-Motion wh=
ich 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) =3D=3D 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 =3D self.focus()
self.tk.call("ttk::treeview::SelectOp", self._w, item, "extend")
return "break"
--_000_0BC70B5D93E054469872FFD0FE07220E0312E0A6C9CERNXCHG51cer_
Content-Type: text/html; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
<html dir=3D"ltr">
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Diso-8859-=
1">
<style type=3D"text/css" id=3D"owaParaStyle"></style>
</head>
<body fpstyle=3D"1" ocsi=3D"0">
<div style=3D"direction: ltr;font-family: Tahoma;color: #000000;font-size: =
10pt;">
<div style=3D"direction:ltr; font-family:Tahoma; color:#000000; font-size:1=
0pt">
<div><span style=3D"font-size:13.3333px">For the moment I came up with this=
solution, which seems to work,</span></div>
<div><span style=3D"font-size:13.3333px">however I am not very happy with i=
t.</span></div>
<div><span style=3D"font-size:13.3333px">I need to define an "anchor&q=
uot; variable to remember from where the selection started</span></div>
<div><span style=3D"font-size:13.3333px"><br>
</span></div>
<div><span style=3D"font-size:13.3333px">class MyTreeview(ttk.Treeview):</s=
pan></div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span> def __init__(self, master, *kw, **args):</span></div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span> super().__init__(master, *kw, **args)</span></div=
>
<div><span style=3D"white-space:pre"></span><span style=3D"font-size: 10pt;=
"> </span><span style=3D"font-size: 10pt;"> </span>=
self.bind("<B1-Motion>", self.b1motion)</div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span> self.bind("<ButtonRelease-1>",&nb=
sp;self.release)</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self.bind("<Up>",self.u=
p)</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self.bind("<Down>",<spa=
n style=3D"white-space: pre;">
</span>self.down)</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self.bind("<Shift-Key-Up>&qu=
ot;,<span style=3D"white-space: pre;">
</span>self.selectUp)</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self.bind("<Shift-Key-Down>&=
quot;,self.selectDown)</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self._anchor =3D ""</span></d=
iv>
<div><span style=3D"font-size:13.3333px"><br>
</span></div>
<div><span style=3D"font-size:13.3333px"> # -------------------=
---------------------------------------------------</span></div>
<div><span style=3D"white-space:pre"></span><span style=3D"font-size: 10pt;=
"> </span>
<span style=3D"font-size: 10pt;"> </span>def b1motion(self, event):</d=
iv>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span># If selected item is the last one focu=
sed</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span># then ignore, otherwise Select is sele=
cting everything</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>if </span>self.identify_row(event.=
y) =3D=3D self.focus(): return</div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self.tk.call("ttk::treeview::Selec=
t", self._w, event.x, event.y, "extend")</span></div>
<div><span style=3D"font-size:13.3333px"><br>
</span></div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span> # -------------------------------------------------------=
---------------</span></div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span> def release(self, event):</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self.tk.call("ttk::treeview::Relea=
se", self._w, event.x, event.y)</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self._anchor =3D self.focus()</span></d=
iv>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>return "break"</span></div>
<div><span style=3D"font-size:13.3333px"><br>
</span></div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span> # -------------------------------------------------------=
---------------</span></div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span> def up(self, event):</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self.tk.call("ttk::treeview::Keyna=
v", self._w, "up")</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self._anchor =3D self.focus()</span></d=
iv>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>return "break"</span></div>
<div><span style=3D"font-size:13.3333px"><br>
</span></div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span> # -------------------------------------------------------=
---------------</span></div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span> def down(self, event):</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self.tk.call("ttk::treeview::Keyna=
v", self._w, "down")</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self._anchor =3D self.focus()</span></d=
iv>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>return "break"</span></div>
<div><span style=3D"font-size:13.3333px"><br>
</span></div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span> # -------------------------------------------------------=
---------------</span></div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span> def selectUp(self, event):</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>if not self._anchor: </span>self._=
anchor =3D self.focus()</div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self.tk.call("ttk::treeview::Keyna=
v", self._w, "up")</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>if self.focus() !=3D self._anchor:</spa=
n></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size: 10pt;"> =
</span><span style=3D"font-size: 10pt;"> </span>self.tk.=
call("ttk::treeview::SelectOp", self._w, self._anchor, "exte=
nd")</div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>return "break"</span></div>
<div><span style=3D"font-size:13.3333px"><br>
</span></div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span> # -------------------------------------------------------=
---------------</span></div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span> def selectDown(self, event):</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>if not self._anchor:</span><span style=
=3D"font-size: 10pt;"> </span><span style=3D"font-size: 10pt;">self._a=
nchor
=3D self.focus()</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>self.tk.call("ttk::treeview::Keyna=
v", self._w, "down")</span></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>if self.focus() !=3D self._anchor:</spa=
n></div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size: 10pt;"> =
</span><span style=3D"font-size: 10pt;"> </span>self.tk.=
call("ttk::treeview::SelectOp", self._w, self._anchor, "exte=
nd")</div>
<div><span style=3D"font-size: 10pt;"> </span><span styl=
e=3D"font-size: 10pt;"> </span><span style=3D"font-size:13.3333px"><sp=
an style=3D"white-space:pre"></span>return "break"</span></div>
<div><br>
</div>
<div style=3D"font-family:Times New Roman; color:#000000; font-size:16px">
<hr tabindex=3D"-1">
<div id=3D"divRpF458632" style=3D"direction:ltr"><font face=3D"Tahoma" size=
=3D"2" color=3D"#000000"><b>From:</b> Tkinter-discuss [tkinter-discuss-boun=
ces+[email protected]] on behalf of Vasilis Vlach=
oudis [[email protected]]<br>
<b>Sent:</b> Tuesday, January 05, 2021 12:06<br>
<b>To:</b> [email protected]<br>
<b>Subject:</b> [Tkinter-discuss] Extend selection in ttk.Treeview<br>
</font><br>
</div>
<div></div>
<div>
<div style=3D"direction:ltr; font-family:Tahoma; color:#000000; font-size:1=
0pt">Hi all,
<div><br>
</div>
<div>I am currently replacing some Listbox() with ttk.Treeview() however th=
e Treeview doesn't have the</div>
<div>"Shift-Up/Down" and "B1-Motion" capabilities to se=
lect with the keyboard multiple items and with the mouse by click and drag.=
</div>
<div><br>
</div>
<div>Looking the treeview.tcl I've managed to add a binding for the B1-Moti=
on which seems to work,</div>
<div>however I failed to find a way to correctly replicate the Listbox beha=
vior with the Shift-Up/Down</div>
<div>This is one of my failed tries</div>
<div><br>
</div>
<div>Any suggestion?</div>
<div><br>
</div>
<div>class MyTreeview(ttk.TreeView):</div>
<div><span style=3D"white-space:pre"></span>def __init__(self, master, *kw,=
**args):</div>
<div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span>super().__init__(master, *kw, **args)</span></div>
<div><span style=3D"white-space:pre"></span>self.bind("<B1-Motion&g=
t;",<span style=3D"white-space:pre">
</span>self.b1motion)</div>
<div>
<div><span style=3D"white-space:pre"></span>self.bind("<Shift-Key-U=
p>",<span style=3D"white-space:pre">
</span>self.selectUp)</div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span>self.bind("<Shift-Key-Down>",<span style=3D"white-spac=
e:pre">
</span>self.selectDown)</span></div>
</div>
<div><br>
</div>
</div>
<div><span style=3D"white-space:pre"></span>def b1motion(self, event):</div=
>
<div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span>if self.identify_row(event.y) =3D=3D self.focus(): return</span></div>
<div><span style=3D"white-space:pre"></span>self.tk.call("ttk::treevie=
w::Select", self._w, event.x, event.y, "extend")</div>
</div>
<div><br>
</div>
<div>
<div><span style=3D"white-space:pre"></span>def selectDown(self, event):</d=
iv>
<div><span style=3D"white-space:pre"></span>self.tk.call("ttk::treevie=
w::Keynav", self._w, "down")</div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span>item =3D self.focus()</span></div>
<div><span style=3D"white-space:pre"></span>self.tk.call("ttk::treevie=
w::SelectOp", self._w, item, "extend")</div>
<div><span style=3D"font-size:13.3333px"><span style=3D"white-space:pre"></=
span>return "break"</span></div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
--_000_0BC70B5D93E054469872FFD0FE07220E0312E0A6C9CERNXCHG51cer_--
--===============6332587465758679377==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
Tkinter-discuss mailing list
[email protected]
https://mail.python.org/mailman/listinfo/tkinter-discuss
--===============6332587465758679377==--