tkcalendar DateEntry类内不显示当日日期,类外可正常显示
问题原因与解决方法
问题根源
你遇到的问题核心在于类内部创建DateEntry时的链式调用写法:
dte_from_date=DateEntry(...).place(...)
place()方法的返回值是None,这意味着变量dte_from_date并没有存储DateEntry的实例,而是None。当Python的垃圾回收机制运行时,没有被引用的DateEntry实例会被回收,导致组件无法正常渲染显示日期;但绑定的StringVar因为还在当前作用域内有引用,所以能正确获取并打印当日日期。
类外部的DateEntry看似正常只是巧合——它的实例可能还没被垃圾回收就进入了主循环,但这种写法本身并不规范。
解决方案
把组件的创建和布局操作分开,先创建DateEntry实例并赋值给变量,再调用place()方法进行布局,确保实例有引用不会被回收:
修改后的完整代码:
# import tk modules import tkinter as tk from tkcalendar import DateEntry class MainWindow(tk.Tk): def __init__(self): super().__init__() # 获取系统屏幕宽高 screen_width = self.winfo_screenwidth() screen_height = self.winfo_screenheight() # 窗口宽高 window_width = 430 window_height = 115 # 窗口居中显示 x = (screen_width - window_width) / 2 y = (screen_height - window_height) / 2 self.geometry('%dx%d+%d+%d' % (window_width, window_height, x, y)) # 窗口不可调整大小 self.resizable(False,False) select_from_date = tk.StringVar() select_to_date = tk.StringVar() # 分开创建和布局,保留DateEntry实例引用 dte_from_date = DateEntry(self, textvariable=select_from_date, date_pattern='dd-mm-yyyy') dte_from_date.place(x=10,y=20) dte_to_date = DateEntry(self, textvariable=select_to_date, date_pattern='dd-mm-yyyy') dte_to_date.place(x=150,y=20) print(select_from_date.get()) print(select_to_date.get()) # 按钮也建议分开写,避免后续需要操作按钮时找不到实例 btn_generate = tk.Button(self, text='Generate') btn_generate.place(x = 10,y = 70) btn_settings = tk.Button(self, text='Settings') btn_settings.place(x = 290,y = 70) def main(): win = MainWindow() select_date = tk.StringVar() # 外部的DateEntry也建议分开写 dte_date = DateEntry(win, textvariable=select_date, date_pattern='dd-mm-yyyy') dte_date.place(x=290,y=20) win.mainloop() if __name__ == '__main__': main()
关键说明
- 所有tkinter组件的布局方法(
place()、pack()、grid())都返回None,所以永远不要用链式调用把组件创建和布局写在一行,否则会丢失组件实例的引用,引发各种异常。 - 保留组件实例的引用不仅能避免垃圾回收问题,还方便后续对组件进行修改(比如修改文本、状态等)。
内容的提问来源于stack exchange,提问作者Ravi Kannan
相关产品推荐
相关产品推荐

