Не удается загрузить календарь с соответствующей датой

from tkinter import *
from tkcalendar import Calendar

def get_date():
    label.configure(text=str(today.get_displayed_month()))
    today.configure(day=str(today.get_date()))

 
win = Tk()
win.title('Calendar Picker')

label = Label(win,text='August 2020')
label.pack(pady=10)

btn = Button(win,text='Pick a date',command=get_date)
btn.pack(pady=10)

today = Calendar(win,selectmode='day',year=2020,month=8,day=6)
today.pack(pady=10)

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python38\lib\tkinter\__init__.py", line 1883, in __call__
    return self.func(*args)
  File "E:\Python\Python Projects Fun\calproject.py", line 6, in get_date
    today.configure(day=str(today.get_date()))
  File "C:\Python38\lib\site-packages\tkcalendar\calendar_.py", line 1612, in configure
    self[item] = value
  File "C:\Python38\lib\site-packages\tkcalendar\calendar_.py", line 518, in __setitem__
    raise AttributeError("Calendar object has no attribute %s." % key)
AttributeError: Calendar object has no attribute day.

Извините, когда я нажал кнопку «Выбрать дату», вылезла вышеуказанная ошибка. Могу я спросить, что мне следует использовать, если я хочу, чтобы соответствующая дата отображалась в верхней части окна при перемещении месяцев? Поскольку я не разбираюсь в документации, может кто-нибудь научить меня этому методу? Каков наилучший способ исправить вышеуказанную ошибку?


person Dominic Sham    schedule 06.08.2020    source источник
comment
FYI today.keys() возвращает список ключевых слов, доступных в .configure(). Если вы хотите изменить текущий выбранный день, используйте today.selection_set(date), хотя я не понимаю, почему вы хотите установить текущую выбранную дату в качестве выбранной даты. Я думаю, что ответ acw1668, вероятно, то, что вы ищете. Если вы хотите убедиться, что выбранная дата видна, используйте today.see(date).   -  person j_4321    schedule 06.08.2020
comment
@ j_4321 Я думаю, что OP хочет, чтобы при изменении месяца он хотел выделить тот же день, что и в предыдущем месяце.   -  person acw1668    schedule 06.08.2020


Ответы (1)


Ошибка в том, что опция day доступна только при создании экземпляра Calendar. Он недоступен в функции configure().

Если вы хотите обновлять label при каждом изменении месяца, вы можете привязать событие <<CalendarMonthChanged>> и обновить label внутри обратного вызова события:

def on_month_changed(event):
    month, year = today.get_displayed_month()
    label.configure(text=today._month_names[month]+' '+str(year))

...

today = Calendar(win, selectmode='day', year=2020, month=8, day=6)
today.pack(pady=10)
today.bind('<<CalendarMonthChanged>>', on_month_changed)

ОБНОВЛЕНИЕ. Если вы хотите выбрать тот же день после изменения месяца, измените функцию get_date(), как показано ниже:

import calendar
...
def get_date():
    month, year = today.get_displayed_month()
    # get the last day of selected month
    _, lastday = calendar.monthrange(year, month)
    # make sure day is valid day in selected month
    day = min(today._sel_date.day, lastday)
    # select the day in selected month
    today.selection_set(today.date(year, month, day))

ОБНОВЛЕНИЕ 2. Ниже приведен пример обновления календаря при выборе даты с помощью tkcalendar.DateEntry:

from tkinter import *
from tkcalendar import Calendar, DateEntry

def date_selected(event):
    date = date_entry.get_date()
    cal.selection_set(date)
 
win = Tk()
win.title('Calendar Picker')

date_entry = DateEntry(win, date_pattern='y-mm-dd', state='readonly')
date_entry.pack()
date_entry.bind('<<DateEntrySelected>>', date_selected)

cal = Calendar(win, selectmode='day', date_pattern='y-mm-dd')
cal.pack(pady=10)

win.mainloop()
person acw1668    schedule 06.08.2020
comment
Я хотел бы иметь кнопку для выбора выбранной даты и перехода к соответствующей дате, так что мне использовать? - person Dominic Sham; 06.08.2020
comment
Он сказал, что календарь не определен после того, как я изменил - person Dominic Sham; 06.08.2020
comment
Вы добавили строку import calendar, как в моем обновленном коде? - person acw1668; 06.08.2020
comment
_, lastday = calendar.monthrange(year, month) что это значит? - person Dominic Sham; 06.08.2020
comment
monthrange(year, month) возвращает день недели первого дня месяца и количество дней в месяце для указанных года и месяца. - person acw1668; 06.08.2020
comment
Я могу захотеть сделать так, чтобы при нажатии кнопки можно было выбрать конкретную дату, а затем перейти к соответствующему месяцу и выделить конкретную дату, поэтому как мне изменить? - person Dominic Sham; 06.08.2020
comment
После того, как я выбираю конкретную дату, почему календарь не переходит на конкретный месяц? - person Dominic Sham; 06.08.2020
comment
Он отлично работает на моем Python 3 в Windows 10. - person acw1668; 06.08.2020
comment
Любая кнопка после того, как я выбрал из окна ввода? - person Dominic Sham; 06.08.2020
comment
Что ты имеешь в виду? Я не понимаю. - person acw1668; 06.08.2020
comment
Например, запись будет иметь календарные месяцы для выбора дат, но после щелчка нижеприведенный календарь останется неизменным. - person Dominic Sham; 06.08.2020
comment
Теперь по умолчанию — август, но когда я выбираю дату из октября, она все равно остается в августе. - person Dominic Sham; 06.08.2020
comment
Как я уже сказал, он отлично работает в моей среде Python. Календарь изменится на любой, выбранный в записи даты. - person acw1668; 06.08.2020
comment
Теперь он отлично работает после того, как я использовал обновленные. Спасибо. - person Dominic Sham; 06.08.2020
comment
Пожалуйста, примите ответ, если он решит ваш вопрос. - person acw1668; 06.08.2020
comment
Нажмите, какую кнопку принять? - person Dominic Sham; 06.08.2020
comment
Нажмите кнопку с галочкой под кнопками голосования. - person acw1668; 06.08.2020