ajkula11
ajkula11

Reputation: 31

Why does this simple Tkinter code create two top-level windows?

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

Answers (4)

Bryan Oakley
Bryan Oakley

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

V E X
V E X

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

quamrana
quamrana

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

user19773037
user19773037

Reputation:

Because you called the class two times.

GUI()
GUI().top_level_window.mainloop()
>>>
GUI().top_level_window.mainloop()

Upvotes: 0

Related Questions