以下示例脚本允许在单击鼠标按钮 1 后释放
ttk.Treeview
小部件的根项目,并在释放 ttk.Button
小部件时重新附加分离的项目。但是,我通过操作项目的文本实现了重新附加,我发现这很麻烦,并且在其文本不包含任何索引的情况下并不总是可行。
引用
move
小部件的reattach
(或ttk.Treeview
)方法的文档
def move(self, item, parent, index):
"""Moves item to position index in parent's list of children.
It is illegal to move an item under one of its descendants. If
index is less than or equal to zero, item is moved to the
beginning, if greater than or equal to the number of children,
it is moved to the end. If item was detached it is reattached."""
self.tk.call(self._w, "move", item, parent, index)
具体来说,
If item was detached it is reattached
。
因此,是否有一种更简单的方法可以将分离的项目重新连接回其原始索引位置,而不必执行我的脚本当前正在执行的操作?
脚本:
import tkinter as tk
from tkinter import ttk
class App:
def __init__(self):
self.detached_items = set()
self.root = tk.Tk()
self.tree = ttk.Treeview(self.root)
self.tree.pack(side="top", fill="both")
self.reinsert = ttk.Button(self.root, text= "Reinsert",
command=self.reinsert_items)
self.reinsert.pack(side="top", fill="both")
self.tree.bind("<ButtonRelease-1>", self.detach_selection)
for i in range(10):
self.tree.insert("", "end", text="Item %s" % i)
self.root.mainloop()
def detach_selection(self, event):
selected_items = event.widget.selection()
print(f"{selected_items=}")
for item in selected_items:
self.detached_items.add(item)
event.widget.detach(*selected_items)
def reinsert_items(self):
for iid in self.detached_items.copy():
print(f"{iid=}")
text = self.tree.item(iid)["text"]
print(f"{text=}")
if self.tree.exists(iid):
self.tree.move(iid, "", int(text[5:]))
# self.tree.move(iid, "", "") # "" as index don't work
else:
self.tree.move(iid, "", "end")
self.detached_items.remove(iid)
print(f"{self.detached_items=}")
if __name__ == "__main__":
app = App()
谢谢@acw1668。
我已将
self.items_index
设置为对 dict
对象的引用,以在分离任何项目之前存储每个项目的索引。此后,访问此 dict
对象以获取相应的项目索引以重新附加项目。
工作脚本:
import tkinter as tk
from tkinter import ttk
class App:
def __init__(self):
self.detached_items = set()
self.items_index = {} # Added
self.root = tk.Tk()
self.tree = ttk.Treeview(self.root)
self.tree.pack(side="top", fill="both")
self.reinsert = ttk.Button(self.root, text= "Reinsert",
command=self.reinsert_items)
self.reinsert.pack(side="top", fill="both")
self.tree.bind("<ButtonRelease-1>", self.detach_selection)
for i in range(10):
self.tree.insert("", "end", text="Item %s" % i)
# Get items index
for item in self.tree.get_children(): # Added
self.items_index[item] = self.tree.index(item) # Added
print(f'{self.items_index=}')
self.root.mainloop()
def detach_selection(self, event):
selected_items = event.widget.selection()
print(f"{selected_items=}")
for item in selected_items:
self.detached_items.add(item)
event.widget.detach(*selected_items)
print(f"{self.detached_items=}")
def reinsert_items(self):
for iid in self.detached_items.copy():
print(f"{iid=}")
index = self.items_index[iid] # Amended
print(f"{index=}")
if self.tree.exists(iid):
self.tree.move(iid, "", index)
else:
self.tree.move(iid, "", "end")
self.detached_items.remove(iid)
print(f"{self.detached_items=}")
if __name__ == "__main__":
app = App()