I am trying to get a simplistic ttk TreeView table going with per-column sorting using the heading 'command' tag, but it doesn't seem to work right. I'm using the answer to this question for implementing the functionality: Tk treeview column sort
My code:
import tkinter as tk
from tkinter import ttk
def treeview_sort_column(tv, col, reverse):
print('sorting %s!' % col)
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):
print('Moving Index:%r, Value:%r, k:%r' % (index, val, k))
tv.move(k, '', index)
# reverse sort next time
tv.heading(col, command=lambda: treeview_sort_column(tv, col, not reverse))
cols = ('name', 'path', 'time', 'pb')
root = tk.Tk()
root.geometry("700x500")
listbox = ttk.Treeview(root, columns=cols, show="headings")
for each in ('name', 'path', 'time','pb'):
listbox.heading(each,text=each.capitalize(),command=lambda: treeview_sort_column(listbox, each, False))
listbox.column( each, width=tk.font.Font().measure(each.title() ))
if not each == 'path':
listbox.column(each,stretch=False)
if not each == 'name':
listbox.column( each, anchor='center')
listbox.pack(expand=True, fill=tk.BOTH)
root.mainloop()
The problem I am running into is every time I run this, it only sorts by the last column, not by the column your clicking on (verified with the print statement in the treeview_sort_column function). Output I get from clicking on any column in the resulting window:
sorting pb!
sorting pb!
sorting pb!
sorting pb!
sorting pb!
sorting pb!
sorting pb!
sorting pb!
If I change from dynamic creation of each command in the for loop to explicit ones by adding this after the loop then it works as expected (i.e. each column sorts itself).
listbox.heading('name', command=lambda: treeview_sort_column(listbox, 'name', False))
listbox.heading('path', command=lambda: treeview_sort_column(listbox, 'path', False))
listbox.heading('time', command=lambda: treeview_sort_column(listbox, 'time', False))
listbox.heading('pb', command=lambda: treeview_sort_column(listbox, 'pb', False))
produces:
sorting name!
sorting name!
sorting path!
sorting path!
sorting time!
sorting time!
sorting pb!
sorting pb!
Obviously this is a very simplistic example, and my final application actually inserts data into the columns (also has more columns) but since I can't even get this simplified version to work, I'm at a loss. What is wrong with my loop that's causing the lambda functions to get screwed up?
My system:
- Windows 7, 64 bit
- Python 3.3.2