based on examples and Henry's help I have come up with the following code to sort the tree in a tkinter treeview, but it does not work. I do not get any errors but the tree is not sorted. Any help is appreciated.
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))
def SortTree():
columns = ('#0',)
for col in columns:
tree.heading(col, text=col,
command=lambda c=col: treeview_sort_column(tree, c, False))
asked Mar 20, 2019 at 19:16
ironfish
3411 gold badge5 silver badges14 bronze badges
2 Answers 2
Since you are just adding the command to column #0, you don't have to put it in a loop.
from tkinter import ttk
import tkinter as tk
root = tk.Tk()
tree = ttk.Treeview(root,height=10)
tree.pack()
def treeview_sort_column(tv, col, reverse):
l = [(tv.item(k)["text"], k) for k in tv.get_children()] #Display column #0 cannot be set
l.sort(key=lambda t: 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))
tree.heading("#0", command=lambda : treeview_sort_column(tree, "#0", False))
for i in range(10):
tree.insert("",0,text=i)
root.mainloop()
answered Mar 21, 2019 at 8:03
Henry Yik
22.6k5 gold badges21 silver badges44 bronze badges
Sign up to request clarification or add additional context in comments.
3 Comments
ironfish
Thanks again, it was very helpful! Unfortunately I do not have enough Reputation to upvote your answer....
Henry Yik
If it helped, you can check it as the accepted answer.
Zelphir Kaltstahl
For explanation:
treeview.set can apparently not be called on column "#0". So instead of doing that, a different way of getting the value of the treeview items, according to which we want to sort the items. This is apparently done by treeview.item(item)["text"], avoiding the error.As I wanted to sort by column values alphabetically on clicking the specific column header I made an addition to the function in the answer of @Henry Yik and wanted to post for people with the same question in the future.
def treeview_sort_column(tv, col, reverse):
column_index = self.tree["columns"].index(col)
l = [(str(tv.item(k)["values"][column_index]), k) for k in tv.get_children()]
l.sort(key=lambda t: 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))
Comments
lang-py
SortTree? You should get a_tkinter.TclError: Display column #0 cannot be setif you did when you do the sorting with the above code.SortTree(I have some print statements to make sure) and I do not get any errors if I usecolumns = ('#0',), if I usecolumns = ('#0')without a comma then I get_tkinter.TclError: Invalid column index #