Tk treeview column sort Tk treeview column sort tkinter tkinter

Tk treeview column sort


patthoyts from #tcl pointed out that the TreeView Tk demo program had the sort functionality. Here's the Python equivalent of it:

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))[...]


This did not work in python3. Since the Variable was passed by reference, all lambdas ended up refering to the same, last, element in columns.

This did the trick for me:

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


madonius is right, but here you have the full example and a proper, understandable explanation

The answer provided by Sridhar Ratnakumar does not work in python3 (and apparently in python2.7): since the variable is passed by reference, all lambdas end up referring to the same, last, element in columns.

You just need to change this for loop:

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

And the same change has to be applied to the lambda function inside treeview_sort_column

So the complete solution would look like this:

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))[...]