سؤال

أحاول استخدام وظيفة الفرز ttk.Treeview الموضحة في إجابة هذا السؤال (Tk فرز عمود Treeview) ويعمل بشكل جيد مع سلاسل مثل 'abc'، و'bcd'، و'cde'، وما إلى ذلك، ولكن عندما أحاول فرز الأرقام، ينتهي الأمر بالظهور على النحو التالي:

1
10
11
2
3
...

أرغب في فرز البيانات بحيث يكون الإخراج:

1
2
3
...
10
11

أعلم أن القيم الموجودة في أعمدة Treeview عبارة عن سلاسل وأنني سأحتاج على الأرجح إلى تحويلها إلى أعداد صحيحة قبل الفرز، لكن لا يمكنني معرفة كيفية القيام بذلك.

هل كانت مفيدة؟

المحلول

list.sort طريقة، sorted وظيفة قبول اختيارية key معامل.يتم استخدام القيمة المرجعة للدالة كمفتاح مقارنة.

تحديد 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()

enter image description here

نصائح أخرى

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