You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Tkinter Treeview中对Badge列数字进行降序排序?

问题:Treeview按Badge列降序排序失效的原因及修复

我希望将Treeview中的Badge列数字按降序(9、7、5、4、3、1)排列,排序时行的顺序也随之改变,期望得到如下结果:

5,"Frank","9"
3,"Daniel","7"
4,"Leonard","5"
1,"Jack","4"
6,"Robert","3"
2,"Tom","1"
但我的代码无法实现该效果,请问代码中存在什么问题?

原代码

from tkinter import *
from tkinter import ttk

ws = Tk()
ws.title('PythonGuides')
ws.geometry('400x300')
ws['bg']='#fb0'

data  = [
    [1,"Jack","4"],
    [2,"Tom","1"],
    [3,"Daniel","7"],
    [4,"Leonard","5"],
    [5,"Frank","9"],
    [6,"Robert","3"],
    ]

tv = ttk.Treeview(ws)
tv['columns']=('Rank', 'Name', 'Badge')
tv.column('#0', width=0, stretch=NO)
tv.column('Rank', anchor=CENTER, width=80)
tv.column('Name', anchor=CENTER, width=80)
tv.column('Badge', anchor=CENTER, width=80)
tv.heading('#0', text='', anchor=CENTER)
tv.heading('Rank', text='Id', anchor=CENTER)
tv.heading('Name', text='rank', anchor=CENTER)
tv.heading('Badge', text='Badge', anchor=CENTER)
tv.pack()


def func1():
    rows = [(tv.set(item, "Badge"), item) for item in tv.get_children('')]
    rows.sort(reverse=True)

    for index, record in enumerate(data):
        Rank = record[0]
        Name = record[1]
        Badge = record[2]
        
        datagrid = [Rank, Name, Badge]
        tv.insert(parent='', index='end', values=(datagrid))
    

button = Button(ws, text="Button", command = func1)
button.place(x=1, y=1)

ws.mainloop()

代码存在的问题

  • Treeview未初始化加载数据:原代码没有把data中的内容插入到Treeview,点击按钮前Treeview是空的,导致排序逻辑无法获取有效行数据。
  • 排序逻辑未作用于Treeview行顺序:代码中仅对Badge值和行ID的列表做了排序,但没有根据排序结果重新调整Treeview的行顺序,反而直接循环原始data插入新行,完全没用到排序后的结果。
  • 字符串排序而非数字排序:data中的Badge值是字符串类型(如"9"、"7"),直接排序会遵循字符串ASCII规则,若出现两位数字(如"10"和"2")会得到错误排序结果。
  • 未清理原有数据:点击按钮时未删除Treeview中的旧行,直接插入新数据会导致内容重复堆积。

修正后的代码

from tkinter import *
from tkinter import ttk

ws = Tk()
ws.title('PythonGuides')
ws.geometry('400x300')
ws['bg']='#fb0'

data  = [
    [1,"Jack","4"],
    [2,"Tom","1"],
    [3,"Daniel","7"],
    [4,"Leonard","5"],
    [5,"Frank","9"],
    [6,"Robert","3"],
    ]

tv = ttk.Treeview(ws)
tv['columns']=('Rank', 'Name', 'Badge')
tv.column('#0', width=0, stretch=NO)
tv.column('Rank', anchor=CENTER, width=80)
tv.column('Name', anchor=CENTER, width=80)
tv.column('Badge', anchor=CENTER, width=80)
tv.heading('#0', text='', anchor=CENTER)
tv.heading('Rank', text='Id', anchor=CENTER)
tv.heading('Name', text='rank', anchor=CENTER)
tv.heading('Badge', text='Badge', anchor=CENTER)
tv.pack()

# 初始化加载数据到Treeview
for record in data:
    tv.insert(parent='', index='end', values=record)

def func1():
    # 获取所有行的Badge值(转成数字)和行ID,按数字降序排序
    rows = [(int(tv.set(item, "Badge")), item) for item in tv.get_children('')]
    rows.sort(reverse=True, key=lambda x: x[0])
    
    # 清空Treeview原有内容
    for item in tv.get_children(''):
        tv.delete(item)
    
    # 根据排序结果重新插入数据
    for _, item_id in rows:
        # 获取该行的原始数据
        values = tv.item(item_id)['values']
        tv.insert(parent='', index='end', values=values)

button = Button(ws, text="Button", command=func1)
button.place(x=1, y=1)

ws.mainloop()

内容的提问来源于stack exchange,提问作者aesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 02:59:58