You can add a "disabled" tag and check in the _box_click()
function that is called when the user clicks in the tree that the item is not disabled before changing its state.
In the code below I copied the source code of the _box_click()
method and added
if self.tag_has("disabled", item):
return # do nothing when disabled
to disable the state change.
I also configured the "disabled" tag so that the font is lighter to be able to see disabled items: self.tag_configure("disabled", foreground='grey')
Here the full code with an example:
import ttkwidgets as tw
import tkinter as tk
class CheckboxTreeview(tw.CheckboxTreeview):
def __init__(self, master=None, **kw):
tw.CheckboxTreeview.__init__(self, master, **kw)
# disabled tag to mar disabled items
self.tag_configure("disabled", foreground='grey')
def _box_click(self, event):
"""Check or uncheck box when clicked."""
x, y, widget = event.x, event.y, event.widget
elem = widget.identify("element", x, y)
if "image" in elem:
# a box was clicked
item = self.identify_row(y)
if self.tag_has("disabled", item):
return # do nothing when disabled
if self.tag_has("unchecked", item) or self.tag_has("tristate", item):
self._check_ancestor(item)
self._check_descendant(item)
elif self.tag_has("checked"):
self._uncheck_descendant(item)
self._uncheck_ancestor(item)
root = tk.Tk()
tree = CheckboxTreeview(root)
tree.pack()
tree.insert("", "end", "1", text="1")
tree.insert("1", "end", "11", text="11", tags=['disabled'])
tree.insert("1", "end", "12", text="12")
tree.insert("11", "end", "111", text="111")
tree.insert("", "end", "2", text="2")
root.mainloop()