Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does destructor work when closing a Tkinter toplevel widget?

Tags:

python

tkinter

I'm trying to understand what happens when you close a toplevel window, specifically, at what point it becomes unreferenced and eligible for garbage collection.

I have put together the code below and this works as I would expect. You open the toplevel with the button, close the toplevel with the cross in the corner and the destructor executes its code.

from tkinter import *
from tkinter import ttk


class TestClass(Toplevel):
    def __init__(self, *args, **kwargs):
        Toplevel.__init__(self, *args, **kwargs)

        self.title('A New Window')
        
        print ('window created')        

    def __del__(self):
        print('destructor called')

        
def AButtonPress():
    #create a device window
    new_window = TestClass(root)
    root.wait_window(new_window)
    print("window closed")


root = Tk()

a_button=ttk.Button(root,text="Press Me",command=AButtonPress)
a_button.grid(column=0, row=0)


root.mainloop()

However, when I add any widgets to the toplevel, say for example a label, when you close the toplevel, the destructor is no longer called.

from tkinter import *
from tkinter import ttk


class TestClass(Toplevel):
    def __init__(self, *args, **kwargs):
        Toplevel.__init__(self, *args, **kwargs)

        self.title('A New Window')
        
        print ('window created')        
 
        #create a widget
        self.a_label=ttk.Label(self,width=15,text = "A Label")
        self.a_label.grid(column=0, row=0)
   

    def __del__(self):
        print('destructor called')

        
def AButtonPress():
    #create a toplevel object
    new_window = TestClass(root)
    root.wait_window(new_window)
    print("window closed")


root = Tk()

a_button=ttk.Button(root,text="Press Me",command=AButtonPress)
a_button.grid(column=0, row=0)


root.mainloop()

Does this now mean that the toplevel will no longer get garbage collected and repeated opening and closing of the toplevel will consume memory?

Am I looking too much into this?

like image 473
r_czw20 Avatar asked Dec 16 '25 21:12

r_czw20


1 Answers

Here is some demo code that deletes all the children of a Toplevel and enforces the garbage collector to remove them from memory:

import tkinter as tk

root = tk.Tk()

def on_closing():
    for child in newwin.winfo_children():
        child.destroy() # Remove them from the window
        del(child) # Enforce garbage collector
    newwin.destroy()

def open_window():
    global newwin
    newwin = tk.Toplevel()
    newwin.protocol("WM_DELETE_WINDOW", on_closing) # Override window close action
    tk.Label(newwin, text="this is a child element").pack()

tk.Button(text="Open Toplevel", command=open_window).pack()
root.mainloop()

You can use code like this to ensure your toplevels do not consume any program memory once the toplevels outlive their usefulness. Let me know if this helps!

like image 113
Muhammad Hamza Naveed Avatar answered Dec 19 '25 11:12

Muhammad Hamza Naveed



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!