Search code examples
pythonsortingtkintertreeviewttk

python ttk treeview sort numbers


I'm trying to use the ttk.Treeview sort function illustrated in the answer to this question (Tk treeview column sort) and it works just fine for strings like 'abc', 'bcd', 'cde', etc., but when I try to sort numbers it ends up showing up like this:

1
10
11
2
3
...

I'd like for the data to be sorted such that the output is:

1
2
3
...
10
11

I know that the values in the treeview columns are strings and that I'm most likely going to need to convert them to integers before sorting, but I can't figure out how to do that.


Solution

  • list.sort method, sorted function accept optional key parameter. The return value of the function is used as comparison key.

    Specifying key function that convert the treeview item into number will solve your problem.

    Example:

    try:
        from tkinter import *
        from tkinter import ttk
    except ImportError:
        from Tkinter import *
        import ttk
    
    def treeview_sort_column(tv, col, reverse):
        l = [(tv.set(k, col), k) for k in tv.get_children('')]
        l.sort(key=lambda t: int(t[0]), reverse=reverse)
        #      ^^^^^^^^^^^^^^^^^^^^^^^
    
        for index, (val, k) in enumerate(l):
            tv.move(k, '', index)
    
        tv.heading(col,
                   command=lambda: treeview_sort_column(tv, col, not reverse))
    
    root = Tk()
    columns = ('number',)
    treeview = ttk.Treeview(root, columns=columns, show='headings')
    for t in ('1', '10', '11', '2', '3'):
        treeview.insert('', END, values=(t,))
    treeview.pack()
    for col in columns:
        treeview.heading(col, text=col,
                         command=lambda c=col: treeview_sort_column(treeview, c, False))
    
    mainloop()
    

    enter image description here