tkcalendar icon indicating copy to clipboard operation
tkcalendar copied to clipboard

DateEntry widget doesn't appear when arrow is clicked (Python 3.7.3 on macOS)

Open mxtm opened this issue 4 years ago • 30 comments

Running Python 3.7.3 on macOS (installed with Homebrew), the DateEntry widget doesn't appear when the arrow is clicked. Dates can still be manually entered in the field as if it were an Entry field. This occurs in code as simple as is found below:

import tkinter as tk
import tkinter.ttk as ttk
import tkcalendar as tkc

def main():
    root = tk.Tk()

    test_frame = ttk.Frame(root)
    test_frame.pack(side='top', fill='both', expand=True)

    test_date_entry = tkc.DateEntry(test_frame)
    test_date_entry.pack()

    root.mainloop()

if __name__ == '__main__':
    main()

mxtm avatar Jul 09 '19 17:07 mxtm

It is probably related with ttk default theme for OSX. To confirm this, can you try the same code but changing the style to clam instead? (I don't have OSX so I cannot do the test myself)

import tkinter as tk
import tkinter.ttk as ttk
import tkcalendar as tkc

def main():
    root = tk.Tk()
    style = ttk.Style(root)
    style.theme_use('clam')

    test_frame = ttk.Frame(root)
    test_frame.pack(side='top', fill='both', expand=True)

    test_date_entry = tkc.DateEntry(test_frame)
    test_date_entry.pack()

    root.mainloop()

if __name__ == '__main__':
    main()

j4321 avatar Jul 17 '19 11:07 j4321

I have the same issue on MacOS with Python 3.7.4. I tried the above code with 'clam' theme and I do not see the calendar widget when the drop-down button is pressed.

royklleung avatar Jul 18 '19 19:07 royklleung

Ok, thanks for the feedback. It will be complicated for me to identify what's going wrong here because I don't have MacOS. Moreover, I am testing tkcalendar in MacOS with Travis CI (including checking whether the calendar appears when clicking on the drop-down button) and these tests pass for MacOS 10.13 with python 3.6 and 2.7. Unfortunately I cannot run the tests with python 3.7.

Could you tell me which version of Tcl/Tk you are using? Maybe the issue is coming from here.

j4321 avatar Jul 19 '19 08:07 j4321

I have the same problem on Windows 10. I try your example code above and when I click the drop-down-arrow nothing happens except I get the error message below. The text filed of DateEntry shows the date in ISO-format 2019-07-19 Python 3.7.4, tkinter 8.6.

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Program Files\Python37\lib\tkinter\__init__.py", line 1705, in __call__
    return self.func(*args)
  File "C:\Users\Magnus\AppData\Roaming\Python\Python37\site-packages\tkcalendar\dateentry.py", line 207, in _on_b1_press
    self.drop_down()
  File "C:\Users\Magnus\AppData\Roaming\Python\Python37\site-packages\tkcalendar\dateentry.py", line 278, in drop_down
    date = self.parse_date(self.get())
  File "C:\Users\Magnus\AppData\Roaming\Python\Python37\site-packages\tkcalendar\calendar_.py", line 927, in parse_date
    return parse_date(date, self._properties['locale'])
  File "C:\Users\Magnus\AppData\Roaming\Python\Python37\site-packages\babel\dates.py", line 1168, in parse_date
    return date(year, month, day)
ValueError: day is out of range for month

magnuskson avatar Jul 19 '19 10:07 magnuskson

@magnuskson I am not sure your issue is the same as the one mentioned above since the other people have not reported any error message. In your case it seems that there is an issue with the locale. Can you tell me if setting explicitly the locale, like in the code below, fix things?

import tkinter as tk
from tkcalendar import DateEntry

root = tk.Tk()

tk.Label(root, text='Choose date').pack()

cal = DateEntry(root, locale='en_US')
cal.pack()

Could you also tell me what locale.getdefaultlocale() returns and what cal.cget('locale') returns when you don't set explicitly the locale when creating the DateEntry?

j4321 avatar Jul 19 '19 11:07 j4321

The TCL/TK version ($tcl_version) I'm using is 8.5 and the patch level (patchlevel) is 8.5.9. Thank you for your help.

I also tried on Python 2.7 and the dropdown is blank, as shown below. But I can still click on the blank dropdown to select the date. To get the dropdown to show in Python 2.7, I need to specify padx and pady in cal.pack() call, like cal.pack(padx=10, pady=10) In short, the same script does work in 2.7 with a minor change to pack().

I would like to see how to get tkcalendar working with Python 3.7.

royklleung avatar Jul 19 '19 14:07 royklleung

@royklleung Thanks for the information. I am developing tkcalendar with the latest version of Tcl/Tk (8.6) and Tk 8.6 changelog anounces

a collection of modernizations in appearance and function

which probably means that the ttk themes were modified. This might be why the DateEntry is not working properly. Since Tcl/Tk 8.5 last release was more than 3 years ago I suggest you to try to update it. Moreover, recent python installers for Mac now include Tcl/Tk 8.6 (https://www.python.org/download/mac/tcltk/).

j4321 avatar Jul 19 '19 14:07 j4321

@j4321 Thank you for the response. I realize that when I run python3 -m tkinter, Tkinter uses its private version of TK/TCL library which is 8.6. I believe 8.6 is being used in my case.

royklleung avatar Jul 19 '19 14:07 royklleung

@royklleung Ok, then I have no clue about what's the issue. Can you tell me what the following code prints when you click on the drop-down button?

import tkcalendar as tkc
d = tkc.DateEntry()
d.pack()

def test(event):
    print(d.identify(event.x, event.y))
    print(d._downarrow_name)

d.bind('<1>', test, add=True)

This is just to check whether the program correctly identifies the drop-down button.

j4321 avatar Jul 19 '19 15:07 j4321

Both print output downarrow.

I combine the above test snippet with original example above as follows:

import tkinter as tk
import tkinter.ttk as ttk
import tkcalendar as tkc

def main():
    root = tk.Tk()
    style = ttk.Style(root)
    style.theme_use('clam')

    test_frame = ttk.Frame(root)
    test_frame.pack(side='top', fill='both', expand=True)

    test_date_entry = tkc.DateEntry(test_frame, locale='en_US')
    test_date_entry.pack(padx=10, pady=10)
    def test(event):
    	print("debug1 " + test_date_entry.identify(event.x, event.y))
    	print("debug2 " + test_date_entry._downarrow_name)

    test_date_entry.bind('<1>', test, add=True)

    root.mainloop()

if __name__ == '__main__':
    main()

The output is shown below when I press the dropdown button:

debug1 downarrow
debug2 downarrow

Hope this helps.

royklleung avatar Jul 19 '19 15:07 royklleung

@royklleung Thanks, it means that the click on the drop-down button is well detected so the issue is that the toplevel containing the calendar does not show up. Does test_date_entry.drop_down() make the calendar appear?

j4321 avatar Jul 19 '19 15:07 j4321

I tried but the drop-down calendar does not show.

Here is the snippet:

    def test(event):
    	print("debug1 " + test_date_entry.identify(event.x, event.y))
    	print("debug2 " + test_date_entry._downarrow_name)
    	test_date_entry.drop_down()

royklleung avatar Jul 19 '19 16:07 royklleung

@royklleung Sorry I was not clear enough, the idea was to execute directly drop_down(), can you run the following code instead? (Though I doubt the result will be different)

import tkinter as tk
import tkinter.ttk as ttk
import tkcalendar as tkc

def main():
    root = tk.Tk()
    style = ttk.Style(root)
    style.theme_use('clam')

    test_frame = ttk.Frame(root)
    test_frame.pack(side='top', fill='both', expand=True)

    test_date_entry = tkc.DateEntry(test_frame, locale='en_US')
    test_date_entry.pack(padx=10, pady=10)
    root.after(100, test_date_entry.drop_down)

    root.mainloop()

if __name__ == '__main__':
    main()

j4321 avatar Jul 19 '19 16:07 j4321

I test the above script and the result is the same - that is, no dropdown calendar when pressing the drop-down button.

royklleung avatar Jul 19 '19 16:07 royklleung

@royklleung Looking on the Internet, I think I found a related bug : https://core.tcl-lang.org/tk/tktview/185c8557d95794af74be. I use overrideredirect(True) on the calendar Topevel and it seems that there is a bug in Tcl/Tk 8.6.8 that makes windows with overrideredirect set to true vanish in MacOS. This bug has been closed after the release of version 8.6.9. So if you confirm that you are using Tcl/Tk >= 8.6.8 then this is an upstream bug and all we can do is wait for the next Tcl/Tk release (and use an older one in the meantime).

j4321 avatar Jul 19 '19 16:07 j4321

@magnuskson I have moved your comment in a new issue #44 since this is clearly an unrelated issue.

j4321 avatar Jul 19 '19 16:07 j4321

@j4321 Thank you for your quick response. Yes, my environment is using Tcl/Tk 8.6.8.

royklleung avatar Jul 19 '19 17:07 royklleung

New Tcl\Tk(8.7) was released, did anyone checked it out?

osinmv avatar Sep 25 '19 23:09 osinmv

Hello, did anybody check DateEntry after 3.7.5 release?

osinmv avatar Oct 17 '19 01:10 osinmv

Workaround for now: Calling overrideredirect(False) on _top_cal (the internal Calendar Window) of the instance of DateEntry Widget fixes the problem.

import tkinter as tk
from tkinter import ttk

if __name__ == "__main__":
    root = tk.Tk() 

    test_frame = ttk.Frame(root)
    test_frame.pack(side='top', fill='both', expand=True)

    test_date_entry = DateEntry(test_frame, locale='de_DE')
    test_date_entry.pack(padx=10, pady=10)

    test_date_entry._top_cal.overrideredirect(False)
    
    root.mainloop()

MamtaSt avatar May 11 '20 22:05 MamtaSt

I am also experiencing this in Tk 8.6 on Debian Bullseye on Beaglebone Black.

Setting `<DateEntryInstance>._top_cal.overrideredirect(False)' opens another window with a title at the bottom of my screen (limited to 960x540) where the calendar appears.

mdeweerd avatar Oct 11 '21 22:10 mdeweerd

I can confirm that the bug is still here in Mac OS Catalina, Monterey and Big Sur with Python 3.8. I have included the suggested fix of setting the overrideredirect(False) but still the dropdowns don't work. However a double click on the down arrow sometimes works. It works in Big Sur but not Catalina not sure about Monterrey as I don't have a machine to test with. I asked over on StackOverflow and posted 2 sets of code, one that does work and one that does not.

working and non working code

I have videos of how it's behaving on ubuntu, Win 10 and Big Sur if that helps to see what's going on.

So far additional testing indicates that on Windows machines and on several Linux systems both my working and non-working code work properly

OogieM avatar Feb 10 '22 14:02 OogieM

Hello, did anybody check DateEntry after 3.7.5 release?

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.

OogieM avatar Apr 12 '22 22:04 OogieM

issue is still present in "Monterey" This (below) worked, so guess it will have to be used "Calling overrideredirect(False) on _top_cal (the internal Calendar Window)" G

georgelza avatar Oct 15 '22 13:10 georgelza

Still happening on macOS Monterey, python 3.9.16. I used pip to install tkcalendar. with _top_cal.overrideredirect(False) I still have to click the down arrow several times before the calendar opens as if in a toplevel window.

Megsman avatar Mar 06 '23 14:03 Megsman

was able to get cal to appear using _top_cal.overrideredirect(False) on 3.9 but 3.10 and 3.11 is a no go. the _top_cal.overrideredirect(False) seems to cause a crash on Windows fyi.

0art-vandelay0 avatar May 02 '23 09:05 0art-vandelay0

macOS Ventura on M1 Mac Mini - have to click the down arrow 4 or more times to finally get the calendar to appear. The box appears but it is empty inside (no dates). The same code works fine when I try it on Windows 11.

StephenMNolan avatar May 10 '23 13:05 StephenMNolan

macOS Ventura on M1 Mac Mini - have to click the down arrow 4 or more times to finally get the calendar to appear. The box appears but it is empty inside (no dates). The same code works fine when I try it on Windows 11.

I'm having the exact same issue on a macOS Ventura M2 Max. Using Python 3.11

chenkc805 avatar Jul 14 '23 19:07 chenkc805

Same issue on M2 Mac Mini running Ventrua 13.4.1 Python 3.10.5, and tkcalendar 1.6.1. Click once to get an empty box, click twice to get calendar. This fix from @MamtaSt doesn't work for me.

Workaround for now: Calling overrideredirect(False) on _top_cal (the internal Calendar Window) of the instance of DateEntry Widget fixes the problem.

import tkinter as tk
from tkinter import ttk

if __name__ == "__main__":
    root = tk.Tk() 

    test_frame = ttk.Frame(root)
    test_frame.pack(side='top', fill='both', expand=True)

    test_date_entry = DateEntry(test_frame, locale='de_DE')
    test_date_entry.pack(padx=10, pady=10)

    test_date_entry._top_cal.overrideredirect(False)
    
    root.mainloop()

sjrothfuss avatar Jul 24 '23 15:07 sjrothfuss

Also experiencing this issue. Running macOS Ventura 13.6.2, python 3.11.7.

gitwinst avatar Feb 02 '24 15:02 gitwinst