Reputation: 31
Consider this very simple code snippet:
import tkinter as tk
class GUI:
def __init__(self):
self.top_level_window = tk.Tk()
GUI()
GUI().top_level_window.mainloop()
It creates two top-level windows on my screen. Why?
I thought the first instance would be immediately garbage collected, so that I would only get one window. I have also tried slightly modified version, which I was sure for would create two separate objects, and thus only one window:
a=GUI()
b=GUI()
b.top_level_window.mainloop()
but I was wrong. And I can't think of a reason.
Any help?
Upvotes: 2
Views: 79
Reputation: 385900
I thought the first instance would be immediately garbage collected
The python object that is the instance of GUI
is garbage-collected. However, tkinter creates objects inside of an embedded tcl interpreter, and the tcl interpreter doesn't know anything about python objects. So, while the object is removed from python, the widgets still exist inside the tcl interpreter.
Put another way, garbage collect of a python object doesn't guarantee that the underlying tcl object is deleted. If you want the first window to be destroyed, you must call destroy()
on the instance.
Upvotes: 1
Reputation: 45
You are saying
GUI()
GUI().top_level_window.mainloop()
Which is two windows because you called the class twice like Frost Dream said so all you need to do is delete GUI()
import tkinter as tk
class GUI:
def __init__(self):
self.top_level_window = tk.Tk()
GUI().top_level_window.mainloop()
Upvotes: 3
Reputation: 39354
I think that with tkinter
, the framework itself keeps hold of instances of GUI objects that you create. This defeats any garbage collection that you might assume is going to happen.
You would need to call .destroy()
on any elements you want tkinter to forget.
Upvotes: 1
Reputation:
Because you called the class two times.
GUI()
GUI().top_level_window.mainloop()
>>>
GUI().top_level_window.mainloop()
Upvotes: 0