Search code examples
pythonpython-2.7tkintertk-toolkittoplevel

Tkinter (python 2.7) | determine whether its tk instance or toplevel instance


Question

root1 = tk.Tk()
root2 = tk.Toplevel()

How can I determine from root1 and root2 whether the instance is tk or toplevel?

My situation (for more context)

I open two Tkinter (instance) window using the same myCustomGUI code.

root = tk.Tk()
mainGUI = myCustomGUI(root)
mainGUI.handler.setLevel(logging.INFO)

root2 = tk.Toplevel()
secondGUI = myCustomGUI(root2)
secondGUI.handler.setLevel(logging.ERROR)

In the myCustomGUI class, I created a on_closing() function which runs when the user closes the window (root.protocol("WM_DELETE_WINDOW", self.on_closing)).

In the said function on_closing() I want to have something like this:

def on_closing(self):
    if self.root is tk:
        self.root.quit()
        exit() # exit the whole program OR run some custom exit function
    else: # meaning self.root is Toplevel
        pass
    self.root.destroy()

In other words, when the instance is Toplevel then only destroy it and when the instance is the main window, then quit tkinter and exit the whole program.

Additional notes (NOT relevant to the question)

The purpose of opening two windows with the identical interface is to print debug info in one window and print important info in the other window, thus the interface is the same.

The purpose I created a on_closing() function is because I have to remove the handler from logger.


Solution

  • The simplest solution is to ask tkinter what class the widget is -- not the python class but rather the internal tk class. For the root window it will be Tk, and for a toplevel it will be Toplevel (unless you've explicitly changed it, which would be highly unusual).

    import tkinter as tk
    
    class MyTop(tk.Toplevel):
        pass
    
    root = tk.Tk()
    top = tk.Toplevel(root)
    mytop = MyTop(root)
    
    assert(root.winfo_class() == "Tk")
    assert(top.winfo_class() == "Toplevel")
    assert(mytop.winfo_class() == "Toplevel")