I'm attempting to create a custom search box class named "TkinterEntryBox" based on Tkinter "Entry" widget that would clear its content when left mouse button is pressed inside text entry area. Currently I'm trying to bind a function called "clear" that is a part of custom class that would clear an input in a parent window that would contain instance of "TkinterEntryBox" widget. I read that inheriting from "Entry" class would be a preferred way of resolving my problem, but I would like to use composition instead of inheritance, since I don't want to have "Entry" class "leaking" outside my custom class.
Problem is, that while callback function is called as expected its "event" argument contains bound "Entry" class widget instance and not "TkinterEntryBox" instance. It causes and exception, since "Entry" class does not have an "clear" method.
Is it possible to force Tkinter to bind my custom class instead of "Entry" class, so that "event" argument in callback function would contain my custom class instance under "widget" property, so that I can safely call "clear" method? Moreover, since I'm new to Tkinter and GUI programming could someone, please tell me if such an approach of creation of widgets is a valid one? If not, then I would greatly appreciate some pointers how to improve my code.
Here is a rough idea of what I created so far:
Below is the custom entry class which "clear" method I would like to call through event callback:
class TkinterEntryBox:
def __init__(self, parent_window: BaseWindow, events_to_callbacks_bindings: Dict[str, Callable]):
self._tkinter_entry = Entry(parent_window)
self._bind_callbacks_to_events(events_to_callbacks_bindings)
def clear(self) -> None:
self._tkinter_entry.delete(ENTRY_BOX_POINTER_START_INDEX, ENTRY_BOX_POINTER_TO_END)
def input(self) -> str:
return self._tkinter_entry.get()
def set(self, text: str) -> None:
self._tkinter_entry.insert(ENTRY_BOX_POINTER_START_INDEX, text)
def place(self, placement_orientation: Geometry) -> None:
self._tkinter_entry.pack(side=str(placement_orientation))
def _bind_callbacks_to_events(self, events_to_callbacks_bindings: Dict[str, Callable]) -> None:
for event_name, callback_function in events_to_callbacks_bindings.items():
self._bind_callback_to_event(event_name, callback_function)
def _bind_callback_to_event(self, event_name: str, callback_function: Callable) -> None:
self._tkinter_entry.bind(event_name, callback_function)
Here is how I initialize my custom entry box class:
def _initialize_search_entry_box(self, factory: TkinterWidgetFactory) -> TkinterEntryBox:
events_to_callbacks_bindings = {
EVENT_ON_LEFT_MOUSE_BUTTON_DOWN: self._on_left_mouse_button_down
}
search_entry_box = factory.assemble_entry_box(self, INGREDIENT_SEARCH_BOX_PLACEHOLDER, events_to_callbacks_bindings)
return search_entry_box
And here is an callback function that is called when left mouse button is pressed inside entry box input area:
@staticmethod
def _on_left_mouse_button_down(event) -> None:
event.widget.clear()
The error message I'm getting in above function call is:
AttributeError: 'Entry' object has no attribute 'clear'
Entrymethods to be available? - Bryan Oakley