TkCalendar:尝试在屏幕上同时显示多个DateEntries会导致TclError

问题描述 投票:1回答:1

我目前正在研究一个学校项目,该项目记录公司的员工信息,并根据员工的空缺,工作角色等因素生成轮值。

为了记录员工的假期,我正在使用模块TkCalendar,该模块具有自己的Calendar和DateEntry对象,可用于显示GUI日历信息​​。但是,我最近更换了计算机,用于允许用户添加假期的一段代码不再起作用;似乎在尝试创建第二个DateEntry对象时,TkCalendar引发了一个错误,这似乎暗示着我传递给第二个对象的选项无效。这令人困惑,因为第一个DateEntry对象似乎生成良好。以下是我遇到的问题的测试案例示例:

from tkinter import *
from tkcalendar import DateEntry

class TestApp:
    def __init__(self, root):
        self.root = root
        self.window = Frame(self.root)
        self.window.pack()

        self.label, self.calendar = [], []
        self.font = ('Impact Bold', 13, 'bold')

        labels = ['Select start date:', 'Select end date:']
        for i in range(2):
            self.label.append(Label(self.window, text=labels[i], font=self.font))
            self.label[-1].grid(row=i+1, column=0)

            self.calendar.append(DateEntry(self.window, font=self.font, locale='en_GB', width=15))
            self.calendar[-1].grid(row=i+1, column=3)


if __name__ == '__main__':
    root = Tk()
    app = TestApp(root)
    root.mainloop()

这将产生以下异常:

Traceback (most recent call last):
  File "C:\Users\xav\Documents\Python files\TkCalendar DateEntry test case.py", line 24, in <module>
    app = TestApp(root)
  File "C:\Users\xav\Documents\Python files\TkCalendar DateEntry test case.py", line 18, in __init__
    self.calendar.append(DateEntry(self.window, font=self.font, locale='en_GB', width=15))
  File "C:\Users\xav\AppData\Local\Programs\Python\Python38\lib\site-packages\tkcalendar\dateentry.py", line 105, in __init__
    self._setup_style()
  File "C:\Users\xav\AppData\Local\Programs\Python\Python38\lib\site-packages\tkcalendar\dateentry.py", line 160, in _setup_style
    self.style.map('DateEntry', **maps)
  File "C:\Users\xav\AppData\Local\Programs\Python\Python38\lib\tkinter\ttk.py", line 403, in map
    self.tk.call(self._name, "map", style, *_format_mapdict(kw)),
_tkinter.TclError: Invalid state name r

可以在here中找到TkCalendar文档。感谢您提前提供的帮助!

python-3.x tkinter tkcalendar
1个回答
1
投票
此问题已在tkcalendar https://github.com/j4321/tkcalendar/issues/61中报告,似乎来自python https://bugs.python.org/issue38661中的更改。据我所知,它仅在Windows中发生(我在Linux中将tkcalendar与python 3.8一起使用没有问题)。问题是self.style.map('TCombobox')返回的样式图不是有效的样式图,尽管它过去是而且应该根据ttk.Style.map()文档字符串来使用。

下面是等待python问题解决方案时的临时修复。想法是重写DateEntry的方法,该方法会触发错误,并手动为DateEntry提供正确的样式图(请参见下面的代码)。

from tkcalendar import DateEntry as TkcDateEntry import tkinter as tk class 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)

© www.soinside.com 2019 - 2024. All rights reserved.