How to safely destroy a ScrolledFrame in ttkbootstrap Python?

105 Views Asked by At

I was creating a multipage application using ttkbootsrtap in python. Here is the code for one of those pages:

class EnterDataPage:
    def __init__(self,root):
        self.root = root
        self.scrolled_frame = ScrolledFrame(self.root,height=400)
        self.scrolled_frame.pack(fill=X,expand=YES)

        enter_data_frame = ttk.Frame(self.scrolled_frame, bootstyle=DARK,padding=10)
        enter_data_frame.pack(pady=20,fill=X)

        name_label = ttk.Label(enter_data_frame,text="NAME",font=("Calibri", 14,"bold"),bootstyle="inverse-dark")
        name_label.grid(row=0,column=0,padx=10)
        name_entry = ttk.Entry(enter_data_frame)
        name_entry.grid(row=0,column=1,padx=10)

        date_label = ttk.Label(enter_data_frame,text="DATE",font=("Calibri", 14,"bold"),bootstyle="inverse-dark")
        date_label.grid(row=0,column=2,padx=10)
        date_entry = ttk.DateEntry(enter_data_frame)
        date_entry.grid(row=0,column=3,padx=10)

        add_remove_entry_frame = ttk.Frame(self.scrolled_frame,bootstyle=DARK,padding=10)
        add_remove_entry_frame.pack(pady=10)
        add_button = ttk.Button(add_remove_entry_frame,text="ADD")
        add_button.grid(row=0,column=0,padx=10,pady=10)
        remove_button = ttk.Button(add_remove_entry_frame,text="REMOVE")
        remove_button.grid(row=0,column=1,padx=10,pady=10)

        
        self.back_button = ttk.Button(self.root, text="BACK",command=self.backToHomePage)
        self.back_button.pack(pady=50)

    def clearPage(self):
        self.scrolled_frame.forget()
        self.scrolled_frame.destroy()
        self.back_button.destroy()

    def backToHomePage(self):
        self.clearPage()
        HomePage(self. Root)

The issue is that when the self.scrolled_frame.destroy() function gets called, it shows a bunch of errors and the application crashes.

Here is the error it shows:

Exception in Tkinter callback
Traceback (most recent call last):
  File "/usr/lib/python3.11/tkinter/__init__.py", line 1948, in __call__
    return self.func(*args)
           ^^^^^^^^^^^^^^^^
  File "/home/rohannag/.local/lib/python3.11/site-packages/ttkbootstrap/scrolled.py", line 455, in _on_leave
    self.disable_scrolling()
  File "/home/rohannag/.local/lib/python3.11/site-packages/ttkbootstrap/scrolled.py", line 414, in disable_scrolling
    self._del_scroll_binding(self)
  File "/home/rohannag/.local/lib/python3.11/site-packages/ttkbootstrap/scrolled.py", line 394, in _del_scroll_binding       
    children = parent.winfo_children()
               ^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/tkinter/__init__.py", line 1106, in winfo_children
    self.tk.call('winfo', 'children', self._w)):
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_tkinter.TclError: bad window path name ".!frame.!scrolledframe"

Please help me out. I can't find the solution anywhere. I simply want to destroy the ScrolledFrame in order to load the next page.

1

There are 1 best solutions below

1
On

Note that the object returned by ScrolledFrame() is the internal frame created inside another outer frame (referenced by an attribute container, see official document). So calling its destroy() will only destroy the internal frame, not the outer frame.

You need to destroy the outer frame instead:

def clearPage(self):
    # destroy the outer frame of `ScrolledFrame`
    # which is referenced by the attribute `container`
    self.scrolled_frame.container.destroy()
    self.back_button.destroy()