插入后自动对 ttk 树视图中的条目进行排序

Sorting entries in a ttk treeview automaticly after inserting

有没有一种方法可以实现类似 post python ttk treeview sort numbers 的结果,但无需按标题?最好的方法是在插入项目后立即进行。

要在每次插入新项目后对 Treeview 进行排序,只需在代码中的正确位置添加对排序函数的显式调用。

示例代码:

import tkinter as tk
from tkinter import ttk

counter = 0
numbers = ['1', '10', '11', '2', '3', '4', '24', '12', '5']

def sort_treeview():
    content = [(tv.set(child, column), child) 
                                for child in tv.get_children('')]
    try:
        content.sort(key=lambda t: int(t[0]))
    except:
        content.sort()
    for index, (val, child) in enumerate(content):
        tv.move(child, '', index)

def add_item():
    global counter
    if counter < 8:
        tv.insert('', 'end', values=numbers[counter])
        counter += 1
        # Sort the treeview after the new item was inserted
        # -------------------------------------------------
        sort_treeview()

root = tk.Tk()
column = 'number'
tv = ttk.Treeview(root, columns=column, show='headings')
tv.pack()

button = tk.Button(root, text='Add entry', command=add_item)
button.pack()

root.mainloop()

如果您打算在每次插入新项目时对内容进行排序,那么更有效的方法是将项目插入正确的位置,而不是为每次插入对整个数据进行排序。

这是使用标准 bisect 模块实现此目的的一种方法,其 bisect(a, x) 函数为您提供索引,x 应插入 a 以维护顺序(假定 a 已排序)。在我下面的示例中:

  • 我的整个界面存储在一些 class GUI;
  • 我的树视图名为 self.tree,只有一列;
  • 我的insert_item方法在树中的某个类别下面插入了一个新行(由location指向),并且每个类别下面的项目必须在我的应用程序中单独排序,这就是为什么我只检索该类别的子项。
    from bisect import bisect

    # ... class GUI contains the treeview self.tree ...

    def insert_item(self, location, item_name, item_id):
        """Inserts a new item below the provided location in the treeview,  
        maintaining lexicographic order wrt names."""
        contents = [
            self.tree.item(child)["text"]
            for child in self.tree.get_children(location)
        ]
        self.tree.insert(
            location, bisect(contents, item_name), item_id, text=item_name
        )