I know I am VERY late but, if you go through your code and replace every widget.bind with the function below, which was taken and modified from here
def bindWidget(widget: Widget, event, all:bool=False, func=None):
# https://stackoverflow.com/a/226141/19581763
'''Set or retrieve the binding for an event on a widget'''
try:
_ = widget.__dict__['bindings']
except KeyError:
has_binding_key = False
else:
has_binding_key = True
if not has_binding_key:
setattr(widget, 'bindings', dict())
if func:
if not all:
widget.bind(event, func)
else:
widget.bind_all(event, func)
widget.bindings[event] = func
else:
return(widget.bindings.setdefault(event, None))
Than the function will keep track of every binding for you by setting a attribute called bindings which has both, the event and the function inside of it.
For example:
label.bind('<Button-1>', label.destroy)
Will become:
bindWidget(label, '<Button-1>', func=label.destroy)
After doing that, you can write a simple function which deletes all of the bindings and widgets:
def clear(self): # Self will be your Tk() instance
"""Clears everything on the window, including bindings"""
for child in self.winfo_children():
child.destroy()
if not hasattr(self, 'bindings'):
self.bindings = {}
for event, func in self.bindings.items():
self.unbind_all(event)
self.bindings = {}
There are only 2 caveats with this approach
- Time
- You will have to go through your code to replace every
widget.bind and if you have lots of bindings, than it will take a lot of time
- Readability
bindWidget(label, '<Button-1>', func=label.destroy) is less readable and less clear than label.bind('<Button-1>', label.destroy)
Edit 8/11/2022
Alternatively, you can destroy the entire window and recreate it like this:
window.destroy()
window = Tk()
However, I am not sure if creating a whole Tcl interpreter is good.