有没有办法让日期输入日历显示在空白的日期输入字段中? (Tk日历)
Is there a way to have the date entry calendar show up in a blank Date Entry field? (Tkcalendar)
我使用的是最新版本的 Tkcalendar。只要日期输入字段为空,就不会弹出下拉列表。它抛出这个错误:
Traceback (most recent call last):
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\JEvans\AppData\Roaming\Python\Python39\site-packages\tkcalendar\dateentry.py", line 246, in _on_b1_press
self.drop_down()
File "C:\Users\JEvans\AppData\Roaming\Python\Python39\site-packages\tkcalendar\dateentry.py", line 331, in drop_down
date = self.parse_date(self.get())
File "C:\Users\JEvans\AppData\Roaming\Python\Python39\site-packages\tkcalendar\calendar_.py", line 1223, in parse_date
year = numbers[indexes['Y']]
IndexError: list index out of range
以下是日期输入小部件在程序中的构建方式:
from tkinter import *
from tkinter import ttk
from tkcalendar import *
import tkcalendar
window = Tk()
class DateEntry(tkcalendar.DateEntry):
def _validate_date(self):
if not self.get():
return True # IMPORTANT!!! Validation must return True/False otherwise it is turned off by tkinter engine
return super()._validate_date()
def test():
pass
window.geometry('500x500')
dob = DateEntry(window, date_pattern = 'mm/dd/yyyy', width = 15, background= 'gray61', foreground="white", locale='en_US')
dob.place(x = 125, y =125)
dob.bind("<<DateEntrySelected>>", test)
dob2 = DateEntry(window, date_pattern = 'mm/dd/yyyy', width = 15, background= 'gray61', foreground="white", locale='en_US')
dob2.place(x =200, y =200)
dob2.bind("<<DateEntrySelected>>", test)
window.mainloop()
这是我单击下拉菜单时发生的情况。什么都没有出现,它 returns 上面的错误消息。
是否可以绕过此错误并在不输入日期值的情况下显示下拉列表?
额外说明:当日期输入字段中有日期时,日期输入工作完美。该错误仅在字段为空时出现。
问题是 dropdown
需要这个 entry
的值来生成带有日历的 window。
它似乎通常用当前日期替换 entry
中的空字符串,然后 dropdown
从 entry
.
获取当前日期
您的代码停止替换空字符串,因此其余代码出现问题。
错误显示 parse_date()
当您有空字符串时会出现问题 - 因此它需要替换此方法并检查文本是否为空并使用一些正确的日期(即当前日期)所以 dropdown
会知道在 window 中用日历生成什么。
我检查了源代码(使用 tkcalendar.__file__
的路径),似乎 DateEntry
没有这个功能,但在 __init__
中它设置了 self.parse_date = self._calendar.parse_date
并且它需要不同的替换方法。
它需要 运行 原来的 __init__
以后保留以前的 self.paser_date
并将自己的功能分配给 self.parse_date
.
完整的工作代码
import tkinter as tk # PEP8: `import *` is not preferred
from tkinter import ttk
import tkcalendar
import datetime
#print(tkcalendar.__file__) path to source code (skip __init__.py)
# --- classes ---
class DateEntry(tkcalendar.DateEntry):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.old_parse_date = self.parse_date
self.parse_date = self.new_parse_date
def _validate_date(self):
if not self.get():
return True
return super()._validate_date()
def new_parse_date(self, text):
print(f'parse_date: >{text}<')
if not text:
return datetime.datetime.now() # return some default date
return self.old_parse_date(text) # runs original function
# --- functions ---
def test(event):
print('test:', event)
# --- main ---
window = tk.Tk()
tk.Label(window, text='tkcalendar.DateEntry').pack(padx=5, pady=5)
dob1 = tkcalendar.DateEntry(window, date_pattern='mm/dd/yyyy', locale='en_US')
dob1.pack()
dob1.bind("<<DateEntrySelected>>", test)
tk.Label(window, text='My DateEntry').pack(padx=5, pady=5)
dob2 = DateEntry(window, date_pattern = 'mm/dd/yyyy', locale='en_US')
dob2.pack()
dob2.bind("<<DateEntrySelected>>", test)
window.mainloop()
我使用的是最新版本的 Tkcalendar。只要日期输入字段为空,就不会弹出下拉列表。它抛出这个错误:
Traceback (most recent call last):
File "C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\JEvans\AppData\Roaming\Python\Python39\site-packages\tkcalendar\dateentry.py", line 246, in _on_b1_press
self.drop_down()
File "C:\Users\JEvans\AppData\Roaming\Python\Python39\site-packages\tkcalendar\dateentry.py", line 331, in drop_down
date = self.parse_date(self.get())
File "C:\Users\JEvans\AppData\Roaming\Python\Python39\site-packages\tkcalendar\calendar_.py", line 1223, in parse_date
year = numbers[indexes['Y']]
IndexError: list index out of range
以下是日期输入小部件在程序中的构建方式:
from tkinter import *
from tkinter import ttk
from tkcalendar import *
import tkcalendar
window = Tk()
class DateEntry(tkcalendar.DateEntry):
def _validate_date(self):
if not self.get():
return True # IMPORTANT!!! Validation must return True/False otherwise it is turned off by tkinter engine
return super()._validate_date()
def test():
pass
window.geometry('500x500')
dob = DateEntry(window, date_pattern = 'mm/dd/yyyy', width = 15, background= 'gray61', foreground="white", locale='en_US')
dob.place(x = 125, y =125)
dob.bind("<<DateEntrySelected>>", test)
dob2 = DateEntry(window, date_pattern = 'mm/dd/yyyy', width = 15, background= 'gray61', foreground="white", locale='en_US')
dob2.place(x =200, y =200)
dob2.bind("<<DateEntrySelected>>", test)
window.mainloop()
这是我单击下拉菜单时发生的情况。什么都没有出现,它 returns 上面的错误消息。
是否可以绕过此错误并在不输入日期值的情况下显示下拉列表?
额外说明:当日期输入字段中有日期时,日期输入工作完美。该错误仅在字段为空时出现。
问题是 dropdown
需要这个 entry
的值来生成带有日历的 window。
它似乎通常用当前日期替换 entry
中的空字符串,然后 dropdown
从 entry
.
您的代码停止替换空字符串,因此其余代码出现问题。
错误显示 parse_date()
当您有空字符串时会出现问题 - 因此它需要替换此方法并检查文本是否为空并使用一些正确的日期(即当前日期)所以 dropdown
会知道在 window 中用日历生成什么。
我检查了源代码(使用 tkcalendar.__file__
的路径),似乎 DateEntry
没有这个功能,但在 __init__
中它设置了 self.parse_date = self._calendar.parse_date
并且它需要不同的替换方法。
它需要 运行 原来的 __init__
以后保留以前的 self.paser_date
并将自己的功能分配给 self.parse_date
.
完整的工作代码
import tkinter as tk # PEP8: `import *` is not preferred
from tkinter import ttk
import tkcalendar
import datetime
#print(tkcalendar.__file__) path to source code (skip __init__.py)
# --- classes ---
class DateEntry(tkcalendar.DateEntry):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.old_parse_date = self.parse_date
self.parse_date = self.new_parse_date
def _validate_date(self):
if not self.get():
return True
return super()._validate_date()
def new_parse_date(self, text):
print(f'parse_date: >{text}<')
if not text:
return datetime.datetime.now() # return some default date
return self.old_parse_date(text) # runs original function
# --- functions ---
def test(event):
print('test:', event)
# --- main ---
window = tk.Tk()
tk.Label(window, text='tkcalendar.DateEntry').pack(padx=5, pady=5)
dob1 = tkcalendar.DateEntry(window, date_pattern='mm/dd/yyyy', locale='en_US')
dob1.pack()
dob1.bind("<<DateEntrySelected>>", test)
tk.Label(window, text='My DateEntry').pack(padx=5, pady=5)
dob2 = DateEntry(window, date_pattern = 'mm/dd/yyyy', locale='en_US')
dob2.pack()
dob2.bind("<<DateEntrySelected>>", test)
window.mainloop()