如何修改(例如添加/删除)ttk的值.树视图标签(tkinter)



如何修改(例如添加/删除(ttk.Treeview中选项tags的值?有没有我可以使用的内置tkinter/widget方法?

...
columns = list(range(1,3))
tree = ttk.Treeview(root, columns=columns)
tree.insert('', 'end', iid=1, values=(1,1), tags='1')
...
  1. 如何将值";NEWTAG";到tags='1'?CCD_ 4应该具有值"1""NEWTAG">
  2. 如何将替换"1"添加为"1";NEWTAG";?CCD_ 5值最终应为"0";NEWTAG">
  3. 如果CCD_ 6的值已经是"0";1’和";NEWTAG";,如何删除";NEWTAG";使得CCD_ 7

我认为您需要调用tkinter没有提供的一些internet tcl小部件命令(如注释中所述(。为此,我们使用tk.call方法。我创建了两个函数,并手动将这些函数分配给Treeview对象:

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',)

尽管创建自己的类来实现这一点要好得多。请注意,"OLDTAG"是您预先给物品的任何标签。这不是完全万无一失的,所以可以随意玩耍。

没有任何事件驱动程序的完整代码:

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()

根据tcl文档,ttk.Treeview小部件确实有添加和删除节点或节点列表中标记的命令。然而,官方tkinter包装器中没有提供这些方法;请参阅/usr/lib/python3.8/tkinter/ttk.py中的Treeview类。

基于@JasonYang的评论和@CoolCloud的回答,下面的测试代码说明了如何实现一个包装器来访问ttk.Treeview小部件的tag addtag remove命令。希望这个例子能让tkinter用户受益。

测试代码:请参阅# Methods to add and remove tag(s)部分。有关为什么使用小部件的._w属性的解释,请阅读此问题。

#!/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()

备注:tag addtag remove方法中,items参数必须是列表对象,而不是字符串对象。items参数的元素必须是字符串对象。如果带有空白的字符串对象作为items传入,则会发生_tkinter.TclError。

最新更新