According to the tcl documentation, a ttk.Treeview
widget does have commands to add and remove a tag from a node or a list of nodes. However, these methods are not provided in the official tkinter wrapper; see the Treeview
class in /usr/lib/python3.8/tkinter/ttk.py.
Building on the comment by @JasonYang and answer by @CoolCloud, the test code below illustrates how to implement a wrapper to access the tag add
and tag remove
commands of the ttk.Treeview
widget. Hopes this example can benefit tkinter users.
Test Code: Please see the section on # Methods to add and remove tag(s)
. For an explanation on why the ._w
attribute of a widget is used, please read this question.
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import tkinter as tk
import tkinter.ttk as ttk
class App(ttk.Frame):
def __init__(self, parent=None, *args, **kwargs):
super().__init__(parent)
self.parent = parent
self._create_treeview()
self._test_tag_add_method()
self._test_tag_remove_method()
def _create_treeview(self):
# Create Treeview
self.tree = ttk.Treeview(self, column=('A', 'B'), selectmode="none",
height=7)
self.tree.grid(row=0, column=0, sticky='nsew')
# Setup column heading
self.tree.heading('#0', text="Point", anchor="center")
self.tree.heading('#1', text="x", anchor="center")
self.tree.heading('#2', text="y", anchor="center")
# #0, #01, #02 denotes the 0, 1st, 2nd columns
# Setup column
self.tree.column('#0', anchor="center", width=50)
self.tree.column('#1', anchor="center", width=30)
self.tree.column('#2', anchor="center", width=30)
# Insert nodes
data = [(10, 20), (30, 40), (50, 60)]
for n, d in enumerate(data):
self.tree.insert('', 'end', iid='n'+str(n), text=str(n), value=d,
tag='Current')
node="n5 xxx"
self.tree.insert('', 'end', iid=node, text=node, value=d, tag='Current')
print(f"Nodes with 'Current' tag: {self.tree.tag_has('Current')}")
def _test_tag_add_method(self):
# Add 'House' to tag of node 'n1'
tag = 'House'
self.tag_add(tag, items="n1") # works but incorrect type for items
print(f"Nodes with 'House' tag: {self.tree.tag_has(tag)}")
self.tag_add(tag, items=['n5 xxx']) # Correct way of submitting items
print(f"Nodes with 'House' tag: {self.tree.tag_has(tag)}")
# Add 'NEWTAG' to tag of all nodes
tag = 'NEWTAG'
self.tag_add(tag, items=self.tree.get_children())
print(f"Nodes with 'NEWTAG' tag: {self.tree.tag_has(tag)}")
def _test_tag_remove_method(self):
# Remove 'House' to tag of node 'n1'
tag = 'House'
self.tag_remove(tag, items="n1") # works but incorrect type for items
print(f"Nodes with 'House' tag: {self.tree.tag_has(tag)}")
self.tag_remove(tag, items=['n5 xxx']) # Correct way of submitting items
print(f"Nodes with 'House' tag: {self.tree.tag_has(tag)}")
# Add 'NEWTAG' to tag of all nodes
tag = 'NEWTAG'
self.tag_remove(tag, items=self.tree.get_children())
print(f"Nodes with 'NEWTAG' tag: {self.tree.tag_has(tag)}")
###########################################################################
# Methods to add and remove tag(s)
###########################################################################
def tag_add(self, tag, items=None):
'''Adds the specified tag to each of the listed items. If tag is
already present for a particular item, then the tags for that item are
unchanged. Note: items refers to the iid of the tree nodes and must be
a list object.
'''
if items is None:
self.tk.call(self.tree._w, 'tag', 'add', tag)
else:
self.tk.call(self.tree._w, 'tag', 'add', tag, items)
def tag_remove(self, tag, items=None):
'''Removes the specified tag from each of the listed items. If items is
omitted, removes tag from each item in the tree. If tag is not present
for a particular item, then the tags for that item are unchanged.
Note: items refers to the iid of the tree nodes and must be a list
object.
'''
if items is None:
self.tk.call(self.tree._w, 'tag', 'remove', tag)
else:
self.tk.call(self.tree._w, 'tag', 'remove', tag, items)
###########################################################################
if __name__ == '__main__':
root = tk.Tk()
app = App(root)
app.grid(row=0, column=0, sticky='nsew')
root.rowconfigure(0, weight=1)
root.columnconfigure(0, weight=1)
root.mainloop()
Remark: In both tag add
and tag remove
methods, the items
argument must be a list object and not a string object. The element of the items
argument must be a string object. In the event a string object with white space is passed in as items
, a _tkinter.TclError would occur.
solved How to amend (e.g. add/remove) the values of a ttk.Treeview tag (tkinter)?