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

Tkinter Treeview点击保存后自动按时间排序(无需点表头)失败求助

问题解决:Treeview自动按时间排序失败的修复

你的代码核心问题出在sort_time()方法中——你错误地生成了无效的Treeview项ID(str(z+1)),而不是使用Treeview返回的原始项ID,导致move()方法无法定位到正确的条目。

修正后的核心逻辑

首先修改sort_time()方法,保留每个时间对应的原始项ID,直接对包含时间和项ID的列表排序:

def sort_time(self):
    # 获取所有项的(时间, 项ID)列表
    items = [(self.tree.set(item, 'time'), item) for item in self.tree.get_children('')]
    # 按时间字符串转datetime排序
    items_sorted = sorted(items, key=lambda x: datetime.strptime(x[0], '%H:%M'))
    # 遍历排序后的列表,移动每个项到对应位置
    for index, (_, item_id) in enumerate(items_sorted):
        self.tree.move(item_id, '', index)

然后修改insert()方法,让点击保存后自动触发排序:

def insert(self):
    # 插入新条目
    self.tree.insert('', END, values=(self.c_time.get(), self.e_fio.get()))
    # 插入后自动排序
    self.sort_time()

关键修正点说明

  1. 保留原始项ID:Treeview的每个条目都有唯一的ID(self.tree.get_children()返回的就是这些ID),排序时必须绑定时间和对应的ID,不能自己生成新的字符串ID。
  2. 直接排序元组列表:不用拆分再重组列表,直接对(时间, 项ID)的元组排序,更简洁且不易出错。
  3. 自动触发排序:在insert方法末尾调用sort_time(),实现保存后自动排序,无需手动点击Sort按钮。

完整修正后的代码

import tkinter as tk
from tkinter import ttk
from datetime import datetime

class Main(tk.Frame):
    def __init__(self, root):
        super().__init__(root)
        self.create_calendar()
        self.create_journal()
        self.create_button()

    def create_calendar(self):
        self.journal_frame = tk.Frame(self, borderwidth=1, 
             highlightthickness=5, highlightbackground='red')
        self.journal_frame.grid(row=0, column=0, sticky='ns')
        self.button_frame = tk.Frame(self, borderwidth=1, 
             highlightthickness=5, highlightbackground='red')
        self.button_frame.grid(row=1, column=0)

    def insert(self):
        self.tree.insert('', END, values=(self.c_time.get(), 
                          self.e_fio.get()))
        # 插入后自动排序
        self.sort_time()

    def sort_time(self):
        # 获取(时间, 项ID)列表
        items = [(self.tree.set(item, 'time'), item) for item in self.tree.get_children('')]
        # 按时间排序
        items_sorted = sorted(items, key=lambda x: datetime.strptime(x[0], '%H:%M'))
        # 移动项到对应位置
        for index, (_, item_id) in enumerate(items_sorted):
            self.tree.move(item_id, '', index)

    def create_journal(self):
        columns = ('time', 'client')
        self.tree = ttk.Treeview(self.journal_frame, columns=columns, 
                                  show='headings')
        self.tree.grid(row=0,column=0)
        self.tree.heading('time', text='Time', anchor='center')
        self.tree.heading('client', text='Client', anchor='center')
        self.tree.column('#1', width=50, stretch=True, anchor='e')
        self.tree.column('#2', width=250, stretch=False, 
                            anchor='center')

    def create_button(self):
        self.b_sort = tk.Button(self.journal_frame, text='Sort', 
                                 command=self.sort_time)
        self.b_sort.grid(row=1, column=3, sticky='e')
        self.l_time = tk.Label(self.button_frame, text='Time:')
        self.l_time.grid(row=0, column=0, sticky='w')
        time_options = ['8:00', '8:30', '9:00', '9:30', '10:00', '10:30', 
                 '11:00', '11:30',
                 '12:00', '12:30', '13:00', '13:30', '14:00', 
                  '14:30', '15:00', '15:30',
              '16:00', '16:30', '17:00', '17:30', '18:00', '18:30', 
                 '19:00', '19:30']
        self.c_time = ttk.Combobox(self.button_frame, values=time_options, 
                                     width=5)
        self.c_time.grid(row=0, column=1)
        self.l_fio = tk.Label(self.button_frame, text='Name:')
        self.l_fio.grid(row=1, column=0, sticky='w')
        self.e_fio = tk.Entry(self.button_frame, width=20)
        self.e_fio.grid(row=1, column=1)
        self.b_save = tk.Button(self.button_frame, text='Save', 
                                 command=self.insert)
        self.b_save.grid(row=5, column=1, sticky='e')

if __name__ == '__main__':
    root = tk.Tk()
    win = Main(root)
    win.pack()
    root.title('客户日志')
    root.geometry('1500x800+100+100')
    root.mainloop()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 03:10:41