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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 23:35:18