Tk树视图列排序

19 投票
7 回答
32153 浏览
提问于 2025-04-15 17:24

有没有办法通过点击列来对中的条目进行排序呢?让我惊讶的是,我找不到任何相关的文档或教程。

7 个回答

6

madonius说得对,不过这里有一个完整的例子和一个易于理解的解释。

Sridhar Ratnakumar提供的答案在python3中不管用(在python2.7中似乎也是如此):因为变量是通过引用传递的,所以所有的lambda函数最终都指向了同一个最后的元素。

你只需要修改这个for循环

for col in columns:
    treeview.heading(col, text=col, command=lambda _col=col: \
                     treeview_sort_column(treeview, _col, False))

同样的修改也要应用到treeview_sort_column里面的lambda函数

所以完整的解决方案看起来是这样的:

def treeview_sort_column(tv, col, reverse):
    l = [(tv.set(k, col), k) for k in tv.get_children('')]
    l.sort(reverse=reverse)

    # rearrange items in sorted positions
    for index, (val, k) in enumerate(l):
        tv.move(k, '', index)

    # reverse sort next time
    tv.heading(col, text=col, command=lambda _col=col: \
                 treeview_sort_column(tv, _col, not reverse))

[...]
columns = ('name', 'age')
treeview = ttk.TreeView(root, columns=columns, show='headings')
for col in columns:
    treeview.heading(col, text=col, command=lambda _col=col: \
                     treeview_sort_column(treeview, _col, False))
[...]
30

patthoyts#tcl 频道提到,TreeView Tk 的演示程序有排序功能。下面是它在 Python 中的对应代码:

def treeview_sort_column(tv, col, reverse):
    l = [(tv.set(k, col), k) for k in tv.get_children('')]
    l.sort(reverse=reverse)

    # rearrange items in sorted positions
    for index, (val, k) in enumerate(l):
        tv.move(k, '', index)

    # reverse sort next time
    tv.heading(col, command=lambda: \
               treeview_sort_column(tv, col, not reverse))

[...]
columns = ('name', 'age')
treeview = ttk.TreeView(root, columns=columns, show='headings')
for col in columns:
    treeview.heading(col, text=col, command=lambda: \
                     treeview_sort_column(treeview, col, False))
[...]
28

在Python3中,这个方法不起作用。因为变量是通过引用传递的,所以所有的lambda表达式最终都指向了columns中的最后一个元素。

这个方法对我有效:

for col in columns:
    treeview.heading(col, text=col, command=lambda _col=col: \
                     treeview_sort_column(treeview, _col, False))

撰写回答