pythontkintertreeviewttkwidgetstcltk

How to add and remove individual tkk.Treeview tags using "addtag" and "dtag"?


I have been trying to add and remove individual tags from items in a ttk.Treeview (tkinter). I have seen references to addtag and dtag (dtag deletes specified tags leaving unspecified remaining) but the only examples I can find are related to canvas of which I know nothing. Try as I might I can't work out the right syntax for addtag and dtag that will work with treeview..! The following is a snippet (in the context of canvas) from the book "Modern Tkinter for Busy Python Developers" by Mark Roseman...

"You can assign tags when creating an item using the tags item configuration option. You can add tags later with the addtag method or remove them with the dtags method. You can get the list of tags for an item with the gettags method or return a list of item id numbers having the given tag with the find command."

>>> c = Canvas(root)
>>> c.create_line(10, 10, 20, 20, tags=('firstline', 'drawing'))
1
>>> c.create_rectangle(30, 30, 40, 40, tags=('drawing'))
2
>>> c.addtag('rectangle', 'withtag', 2)
>>> c.addtag('polygon', 'withtag', 'rectangle')
>>> c.gettags(2)
('drawing', 'rectangle', 'polygon')
>>> c.dtag(2, 'polygon')
>>> c.gettags(2)
('drawing', 'rectangle')
>>> c.find_withtag('drawing')
(1, 2)

Here is a snippet from the Tcl/Tk (tkinter under the hood) documentation pertaining to treeview.

pathName tag bind tagName ?sequence? ?script?
pathName tag configure tagName ?option? ?value option value...?
pathName tag has tagName ?item?
pathName tag names
pathName tag add tag items
pathName tag remove tag ?items?

Can anyone help?

Tried...

tree.item(iid, addtag='special')

Expected to add a new tag to any existing tags Got an error, "addtag" not recognised.

Tried...

tree.dtag(iid, 'special')

Expected to remove the tag 'special' leaving the remaining tags unchanged. Got an error, tree has no attribute "dtag"


Solution

  • ttk.Treeview does not have wrapper functions for tag add and tag remove, so you need to call those command using tk.call function:

    tree.tk.call(tree._w, "tag", "add", tag, iid)
    
    tree.tk.call(tree._w, "tag", "remove", tag, iid)
    

    Or you can create a custom class to have those wrapper functions:

    class CTreeview(ttk.Treeview):
        def tag_add(self, item, tags):
            self.tk.call(self._w, "tag", "add", tags, item)
    
        def tag_remove(self, item, tags):
            self.tk.call(self._w, "tag", "remove", tags, item)
    

    Then you can call:

    Note that tree is an instance of the custom class CTreeview.