Search code examples
pythontkinterttkttkbootstrap

Python tkinter/ ttkboostrap dateentry doesn't work when in readonly state


I am working currently with the ttkbootstrap librairy instead of the ttk librairy in the past. I used to use the ttk DateEntry widget in the "readonly" state which worked perfectly fine. However, for some reasons i need to stop using the ttk librairy and instead use the ttkbootstrap one. So i created a ttkbootstrap DateEntry like said in the documentations: https://ttkbootstrap.readthedocs.io/en/latest/styleguide/dateentry/

import ttkbootstrap as tb
from ttkbootstrap import constants

root = tb.Window()
date_entry = tb.DateEntry(root)
date_entry.pack(padx = 10, pady = 10)
date_entry["state"] = "readonly"

root.mainloop()

The 'readonly' state in effective because i can't write with the keboard in the entry. Nevertheless when i try to pick a new date the date doesn't appear to change so that the entry will only be on today's date forever.

enter image description here

I know that this interaction is specifically linked to the ttkbootstrap librairy because the dateentry widget worked perfectly fine in the ttk librairy.

I tried to search in the source code of the DateEntry class but i found nothing that could explain this behavior. I am still sure that this isn't impossible to create a readonly DateEntry as it is one of the most important thing you need in this librairy.


Solution

  • You shouldn't edit the code of ttkbootstrap. It would get overwritten at the next update.

    You can simply create a new class inheriting from DateEntry, defining the state of the entry at init and enabling the field only when you press the button:

    import ttkbootstrap as tb
    
    class CustomDateEntry(tb.DateEntry):
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.entry["state"] = "readonly"
    
        def _on_date_ask(self):
            self.entry["state"] = "normal"
            super()._on_date_ask()
            self.entry["state"] = "readonly"
    
    root = tb.Window()
    date_entry = CustomDateEntry(root)
    date_entry.pack(padx = 10, pady = 10)
    
    root.mainloop()
    

    Edit: calling super()._on_date_ask() instead of writing a new function, as suggested by @acw1668.