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()
关键修正点说明
- 保留原始项ID:Treeview的每个条目都有唯一的ID(
self.tree.get_children()返回的就是这些ID),排序时必须绑定时间和对应的ID,不能自己生成新的字符串ID。 - 直接排序元组列表:不用拆分再重组列表,直接对
(时间, 项ID)的元组排序,更简洁且不易出错。 - 自动触发排序:在
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
相关产品推荐
相关产品推荐

