How do I amend (e.g. add/remove) the values of the option tags
in a ttk.Treeview
? Is there any built in tkinter/widget methods that I can use?
...
columns = list(range(1,3))
tree = ttk.Treeview(root, columns=columns)
tree.insert('', 'end', iid=1, values=(1,1), tags='1')
...
- How do I add the value "NEWTAG" to
tags='1'
?tags
should have the values '1' & "NEWTAG". - How do I add the replace '1' with "NEWTAG"?
tags
value should finally be "NEWTAG". - If the value of
tags
is already "1' and "NEWTAG", how do I remove "NEWTAG" so thattags="1"?
CodePudding user response:
Treeview takes tupels for the tags and can be added or vise versa like below:
import tkinter as tk
from tkinter import ttk
def add_tag_to_tag(old,new):
lst = tree.tag_has(old) #returns list of iid's
for iid in lst:
old_tags = tree.item(iid)['tags']
tree.item(iid,tags=(old_tags,new))
root = tk.Tk()
tree = ttk.Treeview(root,columns=())
tree.pack(fill='x')
for i in range(5):
param = tree['columns'] (f'#{i}',)
tree.configure(columns=param)
for i in range(5):
tree.heading(column=f'#{i}',text=f'text{i}',anchor='w')
tree.column(column=f'#{i}', width=150,minwidth=50,stretch=False)
for i in range(5):
tree.insert('','end',iid=i,values=(i,),tags=(i,),text=str(i))
add_tag_to_tag('1','NEW')
tree.bind('<Button-1>', lambda e:print(tree.item(tree.focus())))
CodePudding user response:
I think what you need is to call some internet tcl widget commands(as mentioned in the comments) that tkinter
does not provide. To do this, we use tk.call
method. I have created two functions and manually assigned those functions to the Treeview
object:
def add_tag(new_tag,iid):
root.tk.call(tree,'tag','add',new_tag,iid)
def replace_tag(new_tag,to_be_replaced,iid=''):
"""If iid is ommited, replaces the old_tag from all the items if it exists"""
if iid:
root.tk.call(tree,'tag','add',new_tag,iid)
root.tk.call(tree,'tag','remove',to_be_replaced,iid)
else:
iids = tree.tag_has(to_be_replaced)
root.tk.call(tree,'tag','remove',to_be_replaced)
for i in iids:
root.tk.call(tree,'tag','add',new_tag,i)
def delete_tag(tag_to_delete,iid=''):
"""If iid is ommited, deletes all the tag from all items"""
if iid:
root.tk.call(tree,'tag','remove',tag_to_delete,iid)
else:
root.tk.call(tree,'tag','remove',tag_to_delete)
tree.add_tag = add_tag
tree.replace_tag = replace_tag
tree.delete_tag = delete_tag
iids = tree.tag_has('OLDTAG')
# Adding a tag to the first item in the treeview
tree.add_tag('NEWTAG',iids[0]) # Choosing the first item
all_tags = tree.item(iids[0],'tags')
print(f'All tag for the given iid: {all_tags}') # ('OLDTAG', 'NEWTAG')
# Replacing the OLDTAG for all items
tree.replace_tag('OLDEST','OLDTAG')
all_tags = tree.item(iids[0],'tags')
print(f'All tag for the given iid: {all_tags}') # ('NEWTAG', 'OLDEST')
# Delete NEWTAG for the first item
tree.delete_tag('NEWTAG',iids[0])
all_tags = tree.item(iids[0],'tags')
print(f'All tag for the given iid: {all_tags}') # ('OLDEST',)
Though it would be much better to create your own class that does this. Do note that 'OLDTAG' is whatever tag you have given to the items pre-hand. It is not fully foolproof, so feel free to play around.
Entire code without any event driven prooceedures:
from tkinter import *
from tkinter import ttk
root = Tk()
tree = ttk.Treeview(root,columns=('No.','Name'),show='headings')
tree.pack()
def add_tag(new_tag,iid):
root.tk.call(tree,'tag','add',new_tag,iid)
def replace_tag(new_tag,to_be_replaced,iid=''):
"""If iid is not specified replaces the old_tag from all the items if it exists"""
if iid:
root.tk.call(tree,'tag','add',new_tag,iid)
root.tk.call(tree,'tag','remove',to_be_replaced,iid)
else:
iids = tree.tag_has(to_be_replaced)
root.tk.call(tree,'tag','remove',to_be_replaced)
for i in iids:
root.tk.call(tree,'tag','add',new_tag,i)
def delete_tag(tag_to_delete,iid=''):
"""If iid is ommited, deletes all the tag from all items"""
if iid:
root.tk.call(tree,'tag','remove',tag_to_delete,iid)
else:
root.tk.call(tree,'tag','remove',tag_to_delete)
lst = [[1,'Me'],[2,'Myself'],[3,'I']]
for i in ('No.','Name'):
tree.heading(i,text=i)
tree.column(i,width=100)
for i in lst:
tree.insert('','end',values=i,tags='OLDTAG')
iids = tree.tag_has('OLDTAG')
tree.add_tag = add_tag
tree.replace_tag = replace_tag
tree.delete_tag = delete_tag
# Adding a tag to the first item in the treeview
tree.add_tag('NEWTAG',iids[0]) # Choosing the first item
all_tags = tree.item(iids[0],'tags')
print(f'All tag for the given iid: {all_tags}') # ('OLDTAG', 'NEWTAG')
# Replacing the OLDTAG for all items
tree.replace_tag('OLDEST','OLDTAG')
all_tags = tree.item(iids[0],'tags')
print(f'All tag for the given iid: {all_tags}') # ('NEWTAG', 'OLDEST')
# Delete NEWTAG for the first item
tree.delete_tag('NEWTAG',iids[0])
all_tags = tree.item(iids[0],'tags')
print(f'All tag for the given iid: {all_tags}') # ('OLDEST',)
root.mainloop()