Python Tkinter中Calendar控件点击日期后get_date返回当日日期问题
解决tkcalendar点击日期后get_date()返回当日日期的问题
问题出在你手动绑定日历内部标签的点击事件时,触发时机早于tkcalendar自身处理日期选择的逻辑——此时日历的选中状态还没更新,get_date()自然只会返回初始的当日日期。
直接用tkcalendar内置的<<CalendarSelected>>事件就能解决,这个事件会在日历完成日期选择更新后触发,确保能拿到正确的选中日期。修改后的代码如下:
import datetime from tkinter import Frame, Button, Tk from tkinter import simpledialog from tkcalendar import Calendar class DateDialog(simpledialog.Dialog): def __init__(self, parent, title, selected: datetime.date = datetime.date.today()): self.calendar = None self.selected_date = selected self.parent = parent self.type = title super().__init__(parent, title) def body(self, frame): horizontal_frame = Frame(self) self.calendar = Calendar(frame, selectmode='day', year=self.selected_date.year, month=self.selected_date.month, day=self.selected_date.day) cancel_button = Button(horizontal_frame, text='Cancel', width=5, command=self.cancel_pressed) self.bind('<Escape>', lambda event: self.cancel_pressed()) # 改用内置的日期选中事件,替代手动绑定内部标签 self.calendar.bind('<<CalendarSelected>>', self.option_changed) self.calendar.pack(side='left') cancel_button.pack(side='right') horizontal_frame.pack() frame.pack() return horizontal_frame def option_changed(self, *args): self.selected_date = self.calendar.get_date() self.destroy() def cancel_pressed(self): self.selected_date = None self.destroy() def buttonbox(self): pass def main(): root = Tk() test = DateDialog(root, 'testing').selected_date print(test) root.mainloop() if __name__ == '__main__': main()
关键修改点:
- 删除了遍历
self.calendar._calendar绑定内部标签点击的代码,避免干扰tkcalendar的原生逻辑 - 替换为
self.calendar.bind('<<CalendarSelected>>', self.option_changed),利用内置事件确保获取到正确的选中日期 - 保留了ESC键取消、Cancel按钮取消的原有功能,同时减少了用户操作步骤
内容的提问来源于stack exchange,提问作者jordanthompson
相关产品推荐
相关产品推荐

