Вопрос

Я пытаюсь использовать функцию сортировки сортировки TTK.treeView, показанную в ответе на этот вопрос ( tkColumn Column Sort ) и работает просто отлично для строк, таких как «ABC», «BCD», «CDE» и т. Д., Но когда я пытаюсь сортировать номера, оно в конечном итоге покажет, как это:

1
10
11
2
3
...
.

Я хотел бы, чтобы данные были отсортированы такой, что вывод:

1
2
3
...
10
11
.

Я знаю, что значения в колонках TreeView - это строки, и что мне, скорее всего, мне нужно будет преобразовать их в целые числа перед сортировкой, но я не могу понять, как это сделать.

Это было полезно?

Решение

ГенеракодицетагCode Метод, list.sort Функция принимает необязательный параметр sorted.Возвратное значение функции используется в качестве сравнения ключа.

Указание функции key, которые преобразуют элемент TreeView на номер, решит вашу проблему.

Пример:

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()
.

Введите описание изображения здесь

Другие советы

I figure I'd add this bit of code for anyone wanting to use the above solution for both regular string sorts and numeric sorts.

def treeview_sort_column(tv, col, reverse):
    l = [(tv.set(k, col), k) for k in tv.get_children('')]
    try:
        l.sort(key=lambda t: int(t[0]), reverse=reverse)
        #      ^^^^^^^^^^^^^^^^^^^^^^^
    except ValueError:
        l.sort(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))        

It took me a while to find a variant of this answer, but I thought I would post an answer for those looking to sort dates as a string (i.e. 'DD/MM/YYYY')

import datetime

def treeview_sort_column(tv, col, reverse):
l = [(tv.set(k, col), k) for k in tv.get_children('')]
    l.sort(key=lambda: x, datetime.datetime.strptime(x[0], '%d/%m/%y'), 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))  
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top