TkCalendar: Trying to display multiple DateEntries on screen simultaneously leads to TclError TkCalendar: Trying to display multiple DateEntries on screen simultaneously leads to TclError tkinter tkinter

TkCalendar: Trying to display multiple DateEntries on screen simultaneously leads to TclError


This issue have been reported in tkcalendar https://github.com/j4321/tkcalendar/issues/61 and seems to come from a change in python https://bugs.python.org/issue38661. As far as I know it happens only in Windows (I use tkcalendar with python 3.8 in linux without issues). The issue is that the style map returned by self.style.map('TCombobox') is not a valid style map, while it used to be and should be according to the ttk.Style.map() docstring.

Below is a temporary fix while waiting for a solution for the python issue. The idea is to override the method of the DateEntry which triggers the error and manually provide the correct style map to the DateEntry (see code below).

from tkcalendar import DateEntry as TkcDateEntryimport tkinter as tkclass DateEntry(TkcDateEntry):    def _setup_style(self, event=None):        # override problematic method to implement fix        self.style.layout('DateEntry', self.style.layout('TCombobox'))        self.update_idletasks()        conf = self.style.configure('TCombobox')        if conf:            self.style.configure('DateEntry', **conf)        # The issue comes from the line below:        maps = self.style.map('TCombobox')        if maps:            try:                self.style.map('DateEntry', **maps)            except tk.TclError:                # temporary fix to issue #61: manually insert correct map                maps = {'focusfill': [('readonly', 'focus', 'SystemHighlight')],                        'foreground': [('disabled', 'SystemGrayText'),                                       ('readonly', 'focus', 'SystemHighlightText')],                        'selectforeground': [('!focus', 'SystemWindowText')],                        'selectbackground': [('!focus', 'SystemWindow')]}                self.style.map('DateEntry', **maps)        try:            self.after_cancel(self._determine_downarrow_name_after_id)        except ValueError:            # nothing to cancel            pass        self._determine_downarrow_name_after_id = self.after(10, self._determine_downarrow_name)