Ad

Using Super() On Tk.TopLevel, But Do Not Generate Second Window?

- 1 answer

I am attempting to implement a trivial MVC application. When super().__init__() is called, two windows are generated in my python application.

What is the appropriate usage when attempting to inherit from tk.TopLevel, when I only want to generate one window?

import tkinter as tk
from tkinter import ttk

class View(tk.Toplevel):
    def __init__(self, controller):
        super().__init__()
        self.controller = controller
        
    def exec_main(self):
        self.mainloop()
        
class Controller:
    def __init__(self):
        self.view = View(self)

if __name__ == '__main__':
    app = Controller()
    app.view.exec_main()

Doing something like super().__init__(master=self) or super().__init__(self) does not seem to be the solution.

An alternative approach would be to do something like this for the main:

import tkinter as tk


class View(tk.Toplevel):
    def __init__(self, master):
        tk.Toplevel.__init__(self, master)

class Controller:
    def __init__(self, root):
        self.view = View(root)

if __name__ == '__main__':
    root = tk.Tk()
    root.withdraw()
    app = Controller(root)
    root.mainloop()

But this seems wasteful.

Ad

Answer

Without exception, every widget except the root window requires a parent. If you don't create a root window then one will be created for you. When you create an instance of Toplevel and call super().__init__(), if you don't have a root window then tkinter will create one for you.

As you've observed, the correct workaround is to explicitly create a root window and then hide it. You have to make sure to give the user a way to destroy this root window since it won't automatically be destroyed when you close the Toplevel windows.

Ad
source: stackoverflow.com
Ad