简体   繁体   中英

Python: Tkinter root window not reappearing

I am currently experiencing some trouble getting the root window for tkinter to hide when a Toplevel window appears and then become visible when it is closed. The toplevel window is suppose to be a configuration window and upon completing, it will configure the root window.

In my main tkinter object class I have it set up like the following:

class OthelloGUIGame:
    def __init__(self):
        '''Create a GUI and prompt for configurations'''
        self._root_window = tkinter.Tk()
        self._root_window.wm_title("Othello")

    def start(self):
        '''Starts the tkinter mainloop and displays the gui'''
        self._root_window.withdraw()
        game_config = GameSetup()
        self._root_window.mainloop()
        game_config.show()
        self._root_window.deiconify()

This works perfectly for hiding the main Tk window, but it seems the deiconfy method is not getting called when I click the 'X' on the top level window.

Just in case it matters here is the basic setup for my toplevel class:

class GameSetup:
    def __init__(self):
        self._root_window = tkinter.Toplevel()
        self._root_window.wm_title("Game Setup")
        self._moves_first = tkinter.StringVar(self._root_window)
        self._arrangement = tkinter.StringVar(self._root_window)
        self._should_win = tkinter.StringVar(self._root_window)

        self._moves_first.set("Black")
        self._arrangement.set("Black in upper-left")
        self._should_win.set("With more discs")

        self._setUpEntries()
        self._setUpDropDowns()

  def show(self)->None:
      '''Show the window'''
      self._root_window.grab_set()
      self._root_window.wait_wind()

Any ideas on why the window is not reappearing?

Generally speaking, you should never have code after mainloop . That is because mainloop won't return until the root window is destroyed. Since it is destroyed, any windows created as children of the root window will also be destroyed. At that point there's really nothing left for your GUI to do besides exit.

So, in your case you're creating this secondary window and waiting for it to be destroyed. That doesn't cause mainloop to exit, and there's no other code that is causing the main window to be deiconified, so it remains hidden.

You need to put the call to deiconify after the code that shows the GameConfig window. This needs to all be before calling mainloop . Typically you would start the game after the GUI initializes, which you can do with after_idle . In other words, the logic needs to be something like this:

def start(self):
    '''Starts the tkinter mainloop and displays the gui'''
    self._root_window.withdraw()
    game_config = GameSetup()
    # N.B. show will not return until the dialog is destroyed
    game_config.show()
    self._root_window.deiconify()

With this, you need to call mainloop somewhere else. Typically you would do that in your intialiation code. For example:

def __init__(self):
    self._root_window = tkinter.Tk()
    ...
    self.after_idle(self.start)
    self._root_window.mainloop()

That creates the window, causes start to be caused once the window has been created, and then starts the event loop. The start method will then create the secondary window, wait for it to be destroyed, and then show the main window.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM