Frage

Ich versuche, die in der Antwort auf diese Frage dargestellte Sortierfunktion ttk.Treeview zu verwenden (Tk-Treeview-Spaltensortierung) und es funktioniert gut für Zeichenfolgen wie „abc“, „bcd“, „cde“ usw., aber wenn ich versuche, Zahlen zu sortieren, sieht es am Ende so aus:

1
10
11
2
3
...

Ich möchte, dass die Daten so sortiert werden, dass die Ausgabe wie folgt aussieht:

1
2
3
...
10
11

Ich weiß, dass die Werte in den Treeview-Spalten Zeichenfolgen sind und dass ich sie höchstwahrscheinlich vor dem Sortieren in Ganzzahlen umwandeln muss, aber ich weiß nicht, wie das geht.

War es hilfreich?

Lösung

list.sort Methode, sorted Funktion akzeptieren optional key Parameter.Als Vergleichsschlüssel wird der Rückgabewert der Funktion verwendet.

Spezifizieren key Eine Funktion, die das Treeview-Element in eine Zahl umwandelt, wird Ihr Problem lösen.

Beispiel:

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

Andere Tipps

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))  
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top