如何将 ttk.Treeview 项目重新附加或移动回其原始位置?

问题描述 投票:0回答:1

以下示例脚本允许在单击鼠标按钮 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()
python tkinter treeview tcl
1个回答
0
投票

谢谢@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()
© www.soinside.com 2019 - 2024. All rights reserved.