Domanda

Sto cercando di utilizzare la funzione di ordinamento TTK.TreeView illustrata nella risposta a questa domanda ( TKTreeView Column Sort ) E funziona bene per stringhe come 'ABC', 'BCD', 'CDE', ecc., Ma quando provo a ordinare i numeri che finisce per mostrare così:

1
10
11
2
3
...
.

Vorrei che i dati vengano ordinati in modo tale che l'output sia:

1
2
3
...
10
11
.

So che i valori nelle colonne TreeView sono stringhe e che probabilmente dovrò convertirle in interi prima di ordinare, ma non riesco a capire come farlo.

È stato utile?

Soluzione

list.sort Metodo, sorted Accetta il parametro key opzionale.Il valore di ritorno della funzione viene utilizzato come tasto di confronto.

Specifica della funzione key che converti l'elemento TreeView in numero risolverà il problema.

Esempio:

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

Inserire l'immagine Descrizione qui

Altri suggerimenti

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))  
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top