1

In my program, I am creating a window from my root tkinter window, and hiding the root using the .withdraw() function. When I try to show the root window again by calling the root class, it does not show and my program exits. Here's a rough outline of my code describing the problem:

 class MainGUI:
    def __init__(self, master):
        self.master = master
        #....Create and .grid() all GUI Widgets....

        # Button for switching to other window
        button = Button(text="CLICKME", command=lambda: self.other_window())

        # Call and define show function at the end of __init__
        self.show()
        def show(self):
            self.master.update()
            self.master.deiconify()

        # Create other window and withdraw self on button click
        def other_window(self):
            OtherGUI(self.master)
            self.master.withdraw()


class OtherGUI:
    def __init__(self, master):
        # Function for returning to main window, calls MainGUI class
        # to create window and withdraws self.
        def main_window():
            MainGUI(self.master)
            self.master.withdraw()

        master = self.master = Toplevel(master)
        #....Create and .grid() all GUI Widgets....

        # Button for switching back to main window
        button = Button(text="CLICKME", command=lambda: self.main_window())

Using print functions in the MainGUI, I was able to see that when trying to switch back to the main window, show() is actually called, and the entire class does appear to be entered.

This puzzles me as I've only really learn how to do this from other forum posts, and using root.update() and .deiconify() seemed to be the solution for most people, however I have no idea why this isn't working.

Does anyone have an idea as to where I'm going wrong here?

Zaxter5
  • 57
  • 1
  • 2
  • 9
  • 1
    I not sure if you indented the `MainGui` methods wrong or if you really forget to put them outside the `__init__`. But in `OtherGui` for sure `main_window` has to be outside the __init__ and have self parameter – Saad Apr 19 '19 at 15:04
  • I think it would be easier to build a class that inherits from `tk` and `toplevel` respectively. Also I do see indention issues here. Normally the use of `update()` will not be needed in most tkinter applications. – Mike - SMT Apr 19 '19 at 15:22

1 Answers1

2

The example you presented will not work for several reason.

#really you should build your gui as an inherited class as it makes things much easier to manage in tkinter.
class MainGUI:
    def __init__(self, master):
        self.master = master


        button = Button(text="CLICKME", command=lambda: self.other_window())
        # no need for lambda expressions here.
        # missing geometry layout... grid(), pack() or place()

        self.show()
        # self.show does nothing here because your show method is improperly indented.
        # your other_window method is also not properly indented.

        def show(self):
            self.master.update()
            self.master.deiconify()

        def other_window(self):
            OtherGUI(self.master)
            self.master.withdraw()


class OtherGUI:
    def __init__(self, master):
        # this function should be its own method.
        def main_window():
            MainGUI(self.master)
            self.master.withdraw()

        master = self.master = Toplevel(master)
        # this is not how you should be defining master.

        button = Button(text="CLICKME", command=lambda: self.main_window())
        # missing geometry layout... grid(), pack() or place()
        # your button command is using a lambda to call a class method but your define it as a function instead.

Here is a simpler version of what you are attempting that will work:

import tkinter as tk


class MainGUI(tk.Tk):
    def __init__(self):
        super().__init__()
        tk.Button(self, text="Open Toplevel", command=self.open_toplevel_window).pack()

    def open_toplevel_window(self):
        OtherGUI(self)
        self.withdraw()


class OtherGUI(tk.Toplevel):
    def __init__(self, master):
        super().__init__()
        tk.Button(self, text="Close top and deiconify main", command=self.main_window).pack()

    def main_window(self):
        self.master.deiconify()
        self.destroy()


MainGUI().mainloop()

As you can see here when you inherit from the tkinter classes that control the main window and toplevel windows it becomes easier to manage them and less code to perform a task.

Mike - SMT
  • 14,784
  • 4
  • 35
  • 79
  • Thanks a lot for this, it works! What is super().__init__() doing exactly? – Zaxter5 Apr 20 '19 at 01:47
  • @Zaxter5 there is already some good post on what `super()` is and why we use it. See this post: [Understanding Python super() with __init__() methods](https://stackoverflow.com/a/576183/7475225) – Mike - SMT Apr 20 '19 at 01:50