'Tkinter DateEntry not allowing selection

I am using a Tkinter DateEntry field to get a "from" and "to" date for a SQL query. I recetnly redid my project, but copied a lot of code over. In my old project, the date entry works fine, however in my new project whenever I try to select a day for any DateEntry fields, it autofills and does not allow me to use the drop-down window.

This link is an example of how it looks in my working project: https://www.plus2net.com/python/tkinter-DateEntry.php

This is the working code:

date_joined_to = DateEntry(container, selectmode="day", year=datetime.now().year,
                           month=datetime.now().month, day=datetime.now().day,
                           date_pattern="yyyy-mm-dd", foreground="black",
                           headersforeground="black", selectforeground="black", 
                           width=10)
date_joined_to.grid(row=4, column=1, sticky="W")
date_joined_to.delete(0, "end")
date_joined_to._top_cal.overrideredirect(False)

This is my code in my new project where the problem occurs:

test_date_to = DateEntry(self.centersearch, selectmode="day", year=datetime.now().year,
                         month=datetime.now().month,
                         day=datetime.now().day, date_pattern="yyyy-mm-dd",
                         foreground="black", headersforeground="black",
                         selectforeground="black", width=10)
test_date_to.grid(row=9, column=1, sticky="E")
test_date_to.delete(0, "end")
test_date_to._top_cal.overrideredirect(False)

I tried removing all keyword arguments to see if those caused it, but the issue persisted.

From my searches it does appear that many people have encountered this before.



Solution 1:[1]

I can't answer as I've seen the same problem and got here looking for an answer. Here is code that shows it. In my case the version that works looks the same but is not in separate classes but instead in one large script file. But for real world problems that's poor coding practice. When I moved it out into classes It no longer works.

This version works

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from tkcalendar import DateEntry

from datetime import datetime
current_day = datetime.now().day
current_month = datetime.now().month
current_year = datetime.now().year

root = tk.Tk()
root.title("Date Demo Works")
# root.minsize(750, 400)
root.geometry("1024x768+0+0")
root.grid()

demo_edit_screen = tk.Toplevel(root)
demo_edit_screen.geometry("1024x768+0+0")
demo_edit_screen.title("Demo Working")
demo_edit_screen.iconify()
demo_edit_screen.withdraw()

def DoNothing():
    tk.messagebox.showinfo(message='This is an info box that Does Nothing')
    print("testing do nothing dialog")

class DemoEdit():
    def __init__(self):
        leftsidebar = tk.Frame(demo_edit_screen, borderwidth=2, relief="raised", width=40)
        leftsidebar.grid(row=0, column=0, rowspan=11, sticky=("NSEW"))
        gohome = ttk.Button(leftsidebar, text="Home", command=DoNothing())
        gohome.grid(row=0, column=0)
        centersearch = tk.Frame(demo_edit_screen, width=850)
        centersearch.grid(row=0, column=1, sticky="W")
        test_date_label = tk.Label(centersearch, text='Test Date Range', anchor="e")
        test_date_label.grid(row=7, column=0, columnspan=2, padx=4)
        test_date_from_label = tk.Label(centersearch, text='From', anchor="w")
        test_date_from_label.grid(row=8, column=0, padx=4)
        test_date_to_label = tk.Label(centersearch, text='To', anchor="w")
        test_date_to_label.grid(row=8, column=1, padx=4)
        test_date_from = DateEntry(centersearch, selectmode="day"
                                   , year=datetime.now().year, month=datetime.now().month, day=datetime.now().day
                                   , date_pattern="yyyy-mm-dd"
                                   , foreground="black", headersforeground="black", selectforeground="black", width=10)
        test_date_from.grid(row=9, column=0, sticky="W")
        test_date_from.delete(0, "end")
        test_date_from._top_cal.overrideredirect(False)
        test_date_to = DateEntry(centersearch, selectmode="day"
                                 , year=datetime.now().year, month=datetime.now().month, day=datetime.now().day
                                 , date_pattern="yyyy-mm-dd"
                                 , foreground="black", headersforeground="black", selectforeground="black", width=10)
        test_date_to.grid(row=9, column=1, sticky="E")
        test_date_to.delete(0, "end")
        test_date_to._top_cal.overrideredirect(False)

    def show_demoedit(self):
        root.withdraw()
        demo_edit_screen.update()
        demo_edit_screen.deiconify()

leftsidebar = tk.Frame(root, borderwidth=2, relief="raised", height=768)
leftsidebar.grid(row=0, column=0, rowspan=8, sticky=("NSEW"))
show_screen = ttk.Button(leftsidebar, text="Show Calendar Screen", command=DemoEdit.show_demoedit(root))
show_screen.grid(row=3, column=0)
demo_edit = DemoEdit()

root.mainloop()

This version does not

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox

from tkcalendar import DateEntry
from datetime import datetime

def DoNothing():
    tk.messagebox.showinfo(message='This is an info box that Does Nothing')
    print("testing do nothing dialog")

class TopScreen(tk.Frame):
    def __init__(self, parent, controller, label_text="sample", *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.controller = controller
        self.parent = parent
        #   Create the choose action sidebar that will go to specific screens
        self.leftsidebar = tk.Frame(self, borderwidth=2, relief="raised", height=768)
        self.leftsidebar.grid(row=0, column=0, rowspan=8, sticky=("NSEW"))
        self.home_label = tk.Label(self.leftsidebar, text=label_text)
        self.home_label.grid(row=0, column=0)


class CSVReportScreen(TopScreen):
    def __init__(self, parent, controller):
        super().__init__(parent, controller, label_text="CSV Report")
        self.controller = controller
        self.parent = parent
        create_csv_files_button = ttk.Button(self.leftsidebar, text="Create .CSV Files", command=DoNothing())
        create_csv_files_button.grid(row=3, column=0, sticky="NSEW")
        #   Top center search section
        self.centersearch = tk.Frame(self, width=850)
        self.centersearch.grid(row=0, column=1, sticky="W")

        test_date_label = tk.Label(self.centersearch, text='Test Date Range', anchor="e")
        test_date_label.grid(row=7, column=0, columnspan=2, padx=4)
        test_date_from_label = tk.Label(self.centersearch, text='From', anchor="w")
        test_date_from_label.grid(row=8, column=0, padx=4)
        test_date_to_label = tk.Label(self.centersearch, text='To', anchor="w")
        test_date_to_label.grid(row=8, column=1, padx=4)
        test_date_from = DateEntry(self.centersearch, selectmode="day"
                                 , year=datetime.now().year, month=datetime.now().month, day=datetime.now().day
                                 , date_pattern="yyyy-mm-dd"
                                 , foreground="black", headersforeground="black", selectforeground="black", width=10)
        test_date_from.grid(row=9, column=0, sticky="W")
        test_date_from.delete(0, "end")
        test_date_from._top_cal.overrideredirect(False)
        test_date_to = DateEntry(self.centersearch, selectmode="day"
                                 , year=datetime.now().year, month=datetime.now().month, day=datetime.now().day
                                 , date_pattern="yyyy-mm-dd"
                                 , foreground="black", headersforeground="black", selectforeground="black", width=10)
        test_date_to.grid(row=9, column=1, sticky="E")
        test_date_to.delete(0, "end")
        test_date_to._top_cal.overrideredirect(False)


class TestApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)
        self.frames = dict()
        # Add each separate screen here. The name is the class for that screen
        trakker_classes = (CSVReportScreen,TopScreen)
        for F in trakker_classes:
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame
            frame.grid(row=0, column=0, sticky="nsew")
        self.show_frame("CSVReportScreen")

    def show_frame(self, page_name):
        # Show a frame for the given page name
        frame = self.frames[page_name]
        frame.tkraise()

if __name__ == "__main__":
    app = TestApp()
    app.mainloop()

DateEntry is a part of tkcalendar. So I have the same question.

OK, I've just spent all day trying all sorts of permutations:

I'm running on MacOS Catalina 10.15.7 (19H1824) I am using PyCharm 2021.03.3 (Professional Edition) Build #Py-213.7172.26, built on March 15, 2022

I am using virtual environments and have tried the following versions with these results:

Python 3.8.3 tkinter 8.6.8 Cannot get the DateEntry dropdown calendar to appear. Doesn't matter whether the _top_cal.overrideredirect(False) is set or not same behavior.

Python version 3.8.10 (v3.8.10:3d8993a744, May 3 2021, 08:55:58) tkinter 8.6.8 DateEntry in the documentation demo code works when the _top_cal.overrideredirect(False) is used. My DateEntry is not working from within a class.

Python 3.9.8 Universal Version tkinter 8.6.11 DateEntry dropdown requires double clicks to display. Doesn't matter whether the _top_cal.overrideredirect(False) is set or not same behavior. Same in both documentation demo code and my code.

Python 3.9.12 Intel tkinter 8.6.8 Cannot get the DateEntry dropdown calendar to appear. Doesn't matter whether the _top_cal.overrideredirect(False) is set or not same behavior. Same in both documentation demo code and my code.

Python 3.10.4 Universal Version tkinter 8.6.121 DateEntry dropdown requires double clicks to display. Doesn't matter whether the _top_cal.overrideredirect(False) is set or not same behavior. Same in both documentation demo code and my code.

A couple of things I learned along the way. The Intel Python installers all seem to include tkinter 8.6.8 The Universal installers seem to grab whatever was the latest for that version of Python.

I was not able to test all the options because for lots of the intervening ones there are no installers. I was not able to install from the source code.

I don't know where to go from here.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1