I am facing an issue where when I want to select a date from a tkCalendar using DateEntry but the the Calendar goes out of screen. Image showing Calendar goes out of screen
I saw a few solutions which I have added the link to below.
- Tkcalendar: Right align calendar dropdown with the DateEntry
- Behaviour of DateEntry in Tkinter Window
They suggest to rewrite the drop_down function to automatically align the calendar. When I use that, the get_date() function does not work and gives the following error.
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\rmijagir\AppData\Local\Programs\Python\Python39\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "D:/task_tracking/scripts/temp.py", line 49, in <lambda>
Button(root,text='Analyse',command=lambda: print(date1.get_date())).grid(column=0)
AttributeError: 'NoneType' object has no attribute 'get_date'
I want to retrieve the selected date and store it in a variable as well as display the entire Calendar on the screen.
My Code is as follows:
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):
"""Display or withdraw the drop-down calendar depending on its current state."""
if self._calendar.winfo_ismapped():
self._top_cal.withdraw()
else:
self._validate_date()
date = self.parse_date(self.get())
h = self._top_cal.winfo_reqheight()
w = self._top_cal.winfo_reqwidth()
x_max = self.winfo_screenwidth()
y_max = self.winfo_screenheight()
# default: left-aligned drop-down below the entry
x = self.winfo_rootx()
y = self.winfo_rooty() + self.winfo_height()
if x + w > x_max: # the drop-down goes out of the screen
# right-align the drop-down
x += self.winfo_width() - w
if y + h > y_max: # the drop-down goes out of the screen
# bottom-align the drop-down
y -= self.winfo_height() + h
if self.winfo_toplevel().attributes('-topmost'):
self._top_cal.attributes('-topmost', True)
else:
self._top_cal.attributes('-topmost', False)
self._top_cal.geometry('+%i+%i' % (x, y))
self._top_cal.deiconify()
self._calendar.focus_set()
self._calendar.selection_set(date)
root = tk.Tk()
tk.Label(root, text='left align').grid(row=0, column=0)
tk.Label(root, text='right align').grid(row=0, column=1)
date1=MyDateEntry(root).grid(row=1, column=0)
date2=MyDateEntry(root, align='right').grid(row=1, column=1)
Button(root,text='Analyse',command=lambda: print(date1.get_date())).grid(column=0)
root.mainloop()