Python TkCalendar DateEntry选日期时日历出屏且get_date()报错
报错原因
你的报错和重写drop_down()方法没有关系,是Tkinter的基础使用误区:
- 所有Tkinter组件的布局方法(
grid()/pack()/place())返回值都是None - 你写
date1=MyDateEntry(root).grid(row=1, column=0)时,date1变量存储的不是日期选择器组件实例,而是grid()返回的空值,后续调用get_date()自然会触发属性不存在的报错。
你写的下拉日历自动避障逻辑本身是可用的,只需要把组件实例化和布局摆放两步代码拆开写即可。
修复后可直接运行的代码
from tkcalendar import DateEntry from datetime import timedelta import tkinter as tk from tkinter import * class MyDateEntry(DateEntry): def __init__(self, master=None, align='left', **kw): DateEntry.__init__(self, master, **kw) self.align = align def drop_down(self): """根据屏幕边界自动调整下拉日历位置,避免超出显示范围""" if self._calendar.winfo_ismapped(): self._top_cal.withdraw() else: self._validate_date() date = self.parse_date(self.get()) cal_height = self._top_cal.winfo_reqheight() cal_width = self._top_cal.winfo_reqwidth() screen_width = self.winfo_screenwidth() screen_height = self.winfo_screenheight() # 默认位置:输入框左对齐,下拉显示在输入框下方 pos_x = self.winfo_rootx() pos_y = self.winfo_rooty() + self.winfo_height() # 右侧超出屏幕则自动右对齐 if pos_x + cal_width > screen_width: pos_x += self.winfo_width() - cal_width # 下方超出屏幕则自动显示在输入框上方 if pos_y + cal_height > screen_height: pos_y -= self.winfo_height() + cal_height # 匹配父窗口置顶状态 self._top_cal.attributes('-topmost', self.winfo_toplevel().attributes('-topmost')) self._top_cal.geometry('+%i+%i' % (pos_x, pos_y)) self._top_cal.deiconify() self._calendar.focus_set() self._calendar.selection_set(date) if __name__ == '__main__': root = tk.Tk() tk.Label(root, text='左对齐测试').grid(row=0, column=0, padx=10, pady=5) tk.Label(root, text='右对齐测试').grid(row=0, column=1, padx=10, pady=5) # 注意:先创建组件实例赋值给变量,再单独调用grid布局 date1 = MyDateEntry(root) date1.grid(row=1, column=0, padx=10, pady=5) date2 = MyDateEntry(root, align='right') date2.grid(row=1, column=1, padx=10, pady=5) Button(root, text='获取日期', command=lambda: print("选中日期1:", date1.get_date(), "\n选中日期2:", date2.get_date())).grid(row=2, column=0, pady=10) root.mainloop()
效果说明
- 下拉日历会自动检测屏幕边界,右侧超出时自动左移对齐输入框右侧,下方超出时自动上移到输入框上方,不会出现显示不全的问题
- 点击按钮可以正常获取两个日期选择器的选中值,无报错
内容的提问来源于stack exchange,提问作者Ruchi M
相关产品推荐
相关产品推荐

