Tkinter StringVar不更新:日期自动显示异常求助
问题解决:Tkinter日期输入框重复显示最后日期
问题根源
所有自动生成的日期输入框绑定了同一个StringVar变量datev,每次更新datev的值时,所有绑定它的控件都会同步刷新成最新值,最终所有输入框都会显示最后一次赋值的日期。
修复方案
- 移除全局
datev,改为为每个Entry创建独立的StringVar实例 - 在
count_date中生成并存储完整的日期字符串列表,后续给每个Entry对应赋值 - 调整
b2函数,创建Entry时直接绑定对应日期的StringVar
修改后的完整代码
import tkinter as tk from tkcalendar import DateEntry from datetime import datetime, date, timedelta my_w = tk.Tk() my_w.geometry("400x300") e1=tk.StringVar() e2=tk.StringVar() lab_from=tk.Label(my_w,text='From') lab_from.grid(row=0,column=0) lab_to=tk.Label(my_w,text='To') lab_to.grid(row=0,column=1) c1=DateEntry(my_w,selectmode='day',textvariable=e1,date_pattern='dd-MM-yyyy') c1.grid(row=1,column=0,padx=15) c2=DateEntry(my_w,selectmode='day',textvariable=e2,date_pattern='dd-MM-yyyy') c2.grid(row=1,column=1,padx=15) b=tk.Button(my_w,text='Reset',command=lambda:reset()) b.grid(row=1,column=2) b1=tk.Button(my_w,text='test',command=lambda:co()) b1.grid(row=1,column=3) # 存储生成的日期字符串列表 date_str_list = [] def count_date(*args): global d1,d2,final_diff, date_str_list date_str_list = [] if e1.get() and e2.get(): # 更简洁的非空判断 d1 = c1.get_date() d2 = c2.get_date() diff = d2 - d1 final_diff = diff.days tday.set(final_diff) # 生成所有日期字符串并存入列表 for i in range(final_diff+1): day = d1 + timedelta(days=i) date_str_list.append(str(day)) print(date_str_list[i]) tday=tk.IntVar() row_list=[] row_list1=[] # 存储每个Entry对应的StringVar,方便后续管理 date_vars = [] def b2(*args): global en,en1,a,a1, date_str_list, date_vars ac=tday.get() rows=len(row_list) rows1=len(row_list1) diff=ac-rows diff1=ac-rows1 if diff == 0: return elif diff > 0: a=[] # 从当前已有的行数开始,对应日期列表的索引 start_idx = rows for i in range(rows+1, rows+diff+1): # 为每个Entry创建独立的StringVar var = tk.StringVar() # 给变量赋值对应的日期 var.set(date_str_list[start_idx]) date_vars.append(var) en=tk.Entry(my_w,textvariable=var) en.grid(row=i+1,column=0,columnspan=3,pady=10) a.append(en) start_idx +=1 row_list.append(a) elif diff < 0: # 删除Entry时同步删除对应的StringVar del_count = abs(diff) del date_vars[-del_count:] for i in range(rows-1, rows-1+diff, -1): for widget in row_list[i]: widget.grid_forget() widget.destroy() del row_list[-1] if diff1 == 0: return elif diff1 > 0: a1=[] for i in range(rows1+1, rows1+diff1+1): en=tk.Entry(my_w,) en.grid(row=i+1,column=1,columnspan=3,pady=10) a1.append(en) row_list1.append(a1) elif diff1 < 0: for i in range(rows1-1, rows1-1+diff1, -1): for widget in row_list1[i]: widget.grid_forget() widget.destroy() del row_list1[-1] def co(): if 'a' in globals(): print(len(a)) if 'a1' in globals(): print(len(a1)) def reset(): global date_str_list, date_vars date_str_list = [] date_vars = [] dt_now=date.today().strftime('%d-%m-%Y') c1.set_date(dt_now) c2.set_date(dt_now) c1.config(maxdate=None) c2.config(mindate=None) # 重置时清空所有生成的Entry for row in row_list: for widget in row: widget.grid_forget() widget.destroy() row_list.clear() for row in row_list1: for widget in row: widget.grid_forget() widget.destroy() row_list1.clear() tday.set(0) tday.trace('w',b2) e1.trace('w',count_date) e2.trace('w',count_date) my_w.mainloop()
关键修改点说明
- 新增
date_str_list存储所有要显示的日期字符串,date_vars存储每个Entry对应的StringVar - 创建Entry时不再绑定全局变量,而是为每个Entry生成独立的StringVar并赋值对应日期
- 重置函数中新增对
date_str_list、date_vars和生成控件的清理逻辑,避免残留
内容的提问来源于stack exchange,提问作者Eten13
相关产品推荐
相关产品推荐

