title: Hiding Tkinter root window while showing modal window
body: <p>I have a TKinter-based application that attempts to manage settings for a game. Users may have multiple versions of this game installed, and in that case, I need to ask the user which installation they want to manage on startup. That part works well enough on its own; the selection dialog pops up after the main window is constructed, and runs modally.</p>
  
  <p>However, due to differences between game versions, it would be useful if I could adapt the interface slightly for those cases. That, however, means I can't really build the main window until I know which installation I'm working on, so it's going to be blank until the user makes a choice.</p>
  
  <p>I would like to hide the root window while this dialog is being shown, but calling <code>withdraw</code> on the root window simply causes the modal dialog to not be shown either - Python just ends up hanging with no CPU usage, and I can't figure out how to get around the problem without having to resort to a non-modal window (and a significantly different control flow, which I'd like to avoid).</p>
  
  <p>Sample code exhibiting the problem and general code structure (Python 2.7):</p>
  
  <pre><code>from Tkinter import *
  from ttk import *
  
  class TkGui(object):
      def __init__(self):
          self.root = root = Tk()
          self.root.withdraw()
          selector = FolderSelection(self.root, ('foo', 'bar'))
          self.root.deiconify()
          print(selector.result)
  
  class ChildWindow(object): #Base class
      def __init__(self, parent, title):
          top = self.top = Toplevel(parent)
          self.parent = parent
          top.title(title)
          f = Frame(top)
          self.create_controls(f)
          f.pack(fill=BOTH, expand=Y)
  
      def create_controls(self, container):
          pass
  
      def make_modal(self, on_cancel):
          self.top.transient(self.parent)
          self.top.wait_visibility() # Python will hang here...
          self.top.grab_set()
          self.top.focus_set()
          self.top.protocol("WM_DELETE_WINDOW", on_cancel)
          self.top.wait_window(self.top) # ...or here, if wait_visibility is removed
  
  class FolderSelection(ChildWindow):
      def __init__(self, parent, folders):
          self.parent = parent
          self.listvar = Variable(parent)
          self.folderlist = None
          super(FolderSelection, self).__init__(parent, 'Select folder')
          self.result = ''
          self.listvar.set(folders)
          self.make_modal(self.cancel)
  
      def create_controls(self, container):
          f = Frame(container)
          Label(
              f, text='Please select the folder '
              'you would like to use.').grid(column=0, row=0)
          self.folderlist = Listbox(
              f, listvariable=self.listvar, activestyle='dotbox')
          self.folderlist.grid(column=0, row=1, sticky="nsew")
          Button(
              f, text='OK', command=self.ok
              ).grid(column=0, row=2, sticky="s")
          self.folderlist.bind("&lt;Double-1&gt;", lambda e: self.ok())
          f.pack(fill=BOTH, expand=Y)
  
      def ok(self):
          if len(self.folderlist.curselection()) != 0:
              self.result = self.folderlist.get(self.folderlist.curselection()[0])
              self.top.protocol('WM_DELETE_WINDOW', None)
              self.top.destroy()
  
      def cancel(self):
          self.top.destroy()
  
  TkGui()
  </code></pre>