Как получить фон для ячейки в tkcalendar?

У меня есть этот календарь, и я хочу получить цвет фона для выбранной ячейки, как я могу это сделать?

Current_Date = str(datetime.today())
Current_Date=Current_Date[0:10].split('-')
cal = Calendar(root, selectmode="day", year=int(Current_Date[0]), 
               month=int(Current_Date[1]), day=int(Current_Date[2]))
cal.pack(pady=20)

person salma baian    schedule 13.12.2020    source источник
comment
Согласно документации, виртуальное <<CalendarSelected>> событие генерируется каждый время, когда пользователь выбирает день с помощью мыши. Это означает, что вы можете написать функцию обработчика событий, чтобы изменить цвет фона выбранной ячейки, а затем bind() эту функцию к событию.   -  person martineau    schedule 13.12.2020
comment
Вы можете использовать cal.cget("selectbackground").   -  person acw1668    schedule 13.12.2020
comment
вам не нужно преобразовывать datetime.toda() в строку, но получить Current_Date.year, Current_Date.month, Current_Date.day   -  person furas    schedule 13.12.2020
comment
Зачем тебе это? Я проверил исходный код и не вижу способа получить прямой доступ к ячейке, но есть скрытый cal._calendar, который хранит все ячейки (в строках). Но если вы хотите изменить фон, вам лучше использовать tags с назначенными цветами.   -  person furas    schedule 13.12.2020


Ответы (1)


Честно говоря, я не знаю, зачем вам нужен доступ к ячейкам и зачем вам нужно знать предысторию ячейки. Если вы хотите изменить цвет в ячейках, вам лучше использовать теги`

Кстати: вам не нужно преобразовывать дату в строку и разделять ее

current_date = datetime.datetime.today()

cal = tkcalendar.Calendar(root, selectmode="day",
                   year=current_date.year, 
                   month=current_date.month,
                   day=current_date.day)

tkcalendar не дает прямого доступа к ячейкам. Но есть скрытый cal._calendar, в котором хранятся все метки, используемые для создания ячеек, и таким образом вы можете попытаться получить доступ к метке, которая вам нужна. Но Label не использует напрямую background, а style, и вам придется преобразовать стиль в фоновый цвет.


Этот код отображает стили для всех ячеек в текущем месяце.

import datetime
import tkinter as tk
import tkcalendar

# --- functions

def on_click():
    #print(cal._calendar)

    # display all `labels` 
    for row in cal._calendar:
        for day in row:
            number = day['text']
            style = day['style']
            background = cal.style.configure(day['style'])['background']
            print('day: {:2} | style: {:27} | background: {}'.format(number, style, background))
            
# --- main ---

root = tk.Tk()

current_date = datetime.datetime.today()  # PEP8: lower_case_namas

cal = tkcalendar.Calendar(root, selectmode="day",
                   year=current_date.year, 
                   month=current_date.month,
                   day=current_date.day)
cal.pack(pady=20, padx=20)
               
button = tk.Button(root, text='Show all styles', command=on_click)
button.pack(pady=(0,20), padx=20)

print(cal.style)
root.mainloop()

Результат:

day: 30 | style: normal_om..!calendar.TLabel | background: gray93
day: 1  | style: normal..!calendar.TLabel    | background: white
day: 2  | style: normal..!calendar.TLabel    | background: white
day: 3  | style: normal..!calendar.TLabel    | background: white
day: 4  | style: normal..!calendar.TLabel    | background: white
day: 5  | style: we..!calendar.TLabel        | background: gray80
day: 6  | style: we..!calendar.TLabel        | background: gray80
day: 7  | style: normal..!calendar.TLabel    | background: white
day: 8  | style: normal..!calendar.TLabel    | background: white
day: 9  | style: normal..!calendar.TLabel    | background: white
day: 10 | style: normal..!calendar.TLabel    | background: white
[...]

Если вы хотите получить доступ при нажатии на ячейку, вам может потребоваться создать собственный класс и перезаписать метод _on_click

import datetime
import tkinter as tk
import tkcalendar

# --- functions

class MyCalendar(tkcalendar.Calendar):
    def _on_click(self, event):
        print('LABEL:', event.widget)
        print('LABEL text :', event.widget['text'])
        print('LABEL style:', event.widget['style'])
        background = cal.style.configure(event.widget['style'])['background']
        print('LABEL background:', background)
        print('---')
        
        # run original `_on_click`
        super()._on_click(event)

   
# --- main ---

root = tk.Tk()

current_date = datetime.datetime.today()  # PEP8: lower_case_namas

cal = MyCalendar(root, selectmode="day",
                   year=current_date.year, 
                   month=current_date.month,
                   day=current_date.day)
cal.pack(pady=20, padx=20)
cal.bind('<<CalendarSelected>>', on_select)

root.mainloop()

Результат (при нажатии некоторых дат в календаре):

LABEL: .!mycalendar.!frame2.!label29
LABEL text : 17
LABEL style: normal..!mycalendar.TLabel
LABEL background: white
---
LABEL: .!mycalendar.!frame2.!label32
LABEL text : 20
LABEL style: we..!mycalendar.TLabel
LABEL background: gray80
---
person furas    schedule 13.12.2020