Question

Je suis en train d'utiliser le ttk.Treeview fonction de tri illustré dans la réponse à cette question (Les savoirs traditionnels treeview colonne de tri) et il fonctionne très bien pour les chaînes de caractères comme 'abc', 'bcd', 'fac', etc., mais quand j'essaie de trier les nombres, il finit par montrer comme ceci:

1
10
11
2
3
...

J'aimerais pour que les données soient triées telle que la sortie est:

1
2
3
...
10
11

Je sais que les valeurs dans le treeview colonnes sont des chaînes de caractères et que je suis plus susceptible de besoin de les convertir en nombres entiers avant de les trier, mais je ne peux pas comprendre comment le faire.

Était-ce utile?

La solution

list.sort la méthode, sorted la fonction accepte en option key le paramètre.La valeur de retour de la fonction est utilisé comme comparaison clé.

La spécification key fonction de convertir le treeview article dans le numéro de résoudre votre problème.

Exemple:

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

Autres conseils

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))  
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top