Search code examples
pythontkinterbindttkbootstrap

How do I use binding with ttkbootstrap.DateEntry to update a Label with the selected date?


I'm using the ttkbootstrap framework mainly because of the modern DateEntry, and it has some useful themes. My goal is to have a DateEntry widget automatically update a Label with the date selected from the DatePickerPopup, but the "<<DateEntrySelected>>" event using .bind() does not work like it does with regular tkinter. My work-around is to use a Button to call my update_label function on-click. What is the virtual event that is generated each time the user selects a date?

Here's my code snippet:

import ttkbootstrap as ttk
from datetime import datetime


def update_label(event):
    selected_date = cal.entry.get()
    date_object = datetime.strptime(selected_date, "%m/%d/%Y")
    formated_date = date_object.strftime("%A, %b %d")
    label.config(text=f"{formated_date}")


root = ttk.Window()
root.geometry("600x400")

# Label
label = ttk.Label(root, text="Today")
label.pack(pady=5)

# DateEntry
cal = ttk.DateEntry(root, bootstyle="primary")
cal.pack(pady=5)
cal.bind("<<DateEntrySelected>>", update_label)  # FIX

root.mainloop()

ttkbootstrap docs: https://ttkbootstrap.readthedocs.io/en/latest/api/widgets/dateentry/

There, it says... "A date entry widget combines the Combobox and a Button with a callback attached to the get_date function. When pressed, a date chooser popup is displayed. The returned value is inserted into the combobox. The date chooser popup will use the date in the combobox as the date of focus..."

The workaround is to use a Button, like so...

btn = ttk.Button(root, text="Update", command=update_label)
btn.pack(pady=5)

Solution

  • You can use StringVar and bind it to calendar.entry:

    from datetime import datetime
    from tkinter import StringVar
    
    import ttkbootstrap as ttk
    
    
    def update_label(sv):
        selected_date = sv.get()
        if selected_date == "":
            return
        date_object = datetime.strptime(selected_date, "%m/%d/%Y")
        formated_date = date_object.strftime("%A, %b %d")
        label.config(text=f"{formated_date}")
    
    
    root = ttk.Window()
    root.geometry("600x400")
    
    # Label
    label = ttk.Label(root, text="Today")
    label.pack(pady=5)
    
    # DateEntry
    cal = ttk.DateEntry(root, bootstyle="primary")
    cal.pack(pady=5)
    
    sv = StringVar()
    sv.trace("w", lambda name, index, mode, sv=sv: update_label(sv))
    cal.entry.configure(textvariable=sv)
    
    
    root.mainloop()
    

    Creates this app:

    enter image description here