title: wxPython: pause main script and wait for button press
body: <p>I am working on a GUI using wxPython. This GUI should dynamically ask to the user several sets of inputs in the same window, updating the window with the new set of inputs after a button "ok" is pressed.</p>
  
  <p>To do this I have a for loop which calls a function that prompts the input controls on the window. I have tried to use the <code>threading.Event</code> class, letting the script wait for the button to be pressed, but python crashes.</p>
  
  <p>Here below is the interested part of the code.</p>
  
  <pre><code>        # Iterate through parameters
          self.cv = threading.Event()
          for key in parameters:
              self.input_sizer = [None]*len(parameters[key])
              self.cv.clear()
              self.make_widgets(key, parameters[key])
              self.cv.wait()
          # Panel final settings
          self.panel.SetSizer(self.main_sizer)
          self.main_sizer.SetSizeHints(self)
  
      def make_widgets(self, request, parameters):
          # Function for widget prompting on the panel
          self.main_sizer = wx.BoxSizer(wx.VERTICAL)
          self.controls = {"request": wx.StaticText(self.panel, label="Please type the new alias' " + request),
                           "txt": [None]*len(parameters),
                           "tc": [None]*len(parameters)}
          self.main_sizer.Add(self.controls["request"], 1, wx.ALL, 10)
          for i in range(len(parameters)):
              self.input_sizer[i] = wx.BoxSizer(wx.HORIZONTAL)
              self.main_sizer.Add(self.input_sizer[i], 1, wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10)
              # Text
              self.controls['txt'][i] = wx.StaticText(self.panel, label=parameters[i])
              self.input_sizer[i].Add(self.controls["txt"][i], 0, wx.ALIGN_CENTER | wx.LEFT, 10)
              # Input
              self.controls['tc'][i] = wx.TextCtrl(self.panel)
              self.input_sizer[i].Add(self.controls["tc"][i], 0, wx.ALIGN_CENTER)
          # Ok button
          self.button_ok = wx.Button(self.panel, label="Ok")
          self.main_sizer.Add(self.button_ok, 1, wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10)
          self.button_ok.Bind(wx.EVT_BUTTON, self.carry_on)
  
      def carry_on(self, event):
          self.cv.set()
  </code></pre>
  
  <p>Does anyone has any idea?</p>
  
  <p>Thanks, here below there's the complete code.</p>
  
  <pre><code>import wx
  from collections import OrderedDict
  import threading
  
  
  ############################################################################
  class AddMainName(wx.Frame):
      # Class definition for main Name addition
      def __init__(self, parent, title):
          # Constructor
          super().__init__(parent, title=title)
          # Run the name addition
          self.set_alias_name()
          self.Centre()
          self.Show()
  
      def set_alias_name(self):
          # Function for definition of alias name
          # Panel
          self.panel = wx.Panel(self)
          # Lists of parameters to be typed
          parameters = OrderedDict([("name parts", [
              "Prefix", "Measurement", "Direction", "Item", "Location", "Descriptor", "Frame", "RTorigin"
              ]),
                                    ("SI units", [
                                        "A", "cd", "K", "kg", "m", "mol", "Offset", "rad", "s", "ScaleFactor"
                                        ]),
                                    ("normal display unit", [
                                        "A", "cd", "K", "kg", "m", "mol", "Offset", "rad", "s", "ScaleFactor"
                                    ]),
                                    ("other parameters", [
                                        "Meaning", "Orientation Convention", "Contact Person", "Note",
                                    ])])
          # Iterate through parameters
          self.cv = threading.Event()
          for key in parameters:
              self.input_sizer = [None]*len(parameters[key])
              self.cv.clear()
              self.make_widgets(key, parameters[key])
              self.cv.wait()
          # Panel final settings
          self.panel.SetSizer(self.main_sizer)
          self.main_sizer.SetSizeHints(self)
  
      def make_widgets(self, request, parameters):
          # Function for widget prompting on the panel
          self.main_sizer = wx.BoxSizer(wx.VERTICAL)
          self.controls = {"request": wx.StaticText(self.panel, label="Please type the new alias' " + request),
                           "txt": [None]*len(parameters),
                           "tc": [None]*len(parameters)}
          self.main_sizer.Add(self.controls["request"], 1, wx.ALL, 10)
          for i in range(len(parameters)):
              self.input_sizer[i] = wx.BoxSizer(wx.HORIZONTAL)
              self.main_sizer.Add(self.input_sizer[i], 1, wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10)
              # Text
              self.controls['txt'][i] = wx.StaticText(self.panel, label=parameters[i])
              self.input_sizer[i].Add(self.controls["txt"][i], 0, wx.ALIGN_CENTER | wx.LEFT, 10)
              # Input
              self.controls['tc'][i] = wx.TextCtrl(self.panel)
              self.input_sizer[i].Add(self.controls["tc"][i], 0, wx.ALIGN_CENTER)
          # Ok button
          self.button_ok = wx.Button(self.panel, label="Ok")
          self.main_sizer.Add(self.button_ok, 1, wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10)
          self.button_ok.Bind(wx.EVT_BUTTON, self.carry_on)
  
      def carry_on(self, event):
          self.cv.set()
  
  
  ############################################################################
  class AddCommonName(wx.Frame):
      # Class definition for common name addition
      def __init__(self, parent, title):
          # Constructor
          super().__init__(parent, title=title,
                           size=(400, 150))
          # Run the name addition
          self.set_alias()
          self.Centre()
          self.Show()
  
      def set_alias(self):
          panel = wx.Panel(self)
          sizer = wx.GridBagSizer(5, 5)
          text1 = wx.StaticText(panel, label="Please type the new alias name.")
          sizer.Add(text1, pos=(0, 0), flag=wx.TOP | wx.LEFT | wx.BOTTOM,
                            border=15)
          panel.SetSizer(sizer)
  
  
  ############################################################################
  class AliasGUI(wx.Frame):
  
      def __init__(self, parent, title):
          # Constructor
          super().__init__(parent, title=title)
          # Run first dialog of the GUI
          self.begin()
          self.Centre()
          self.Show()
  
      def begin(self):
          # Panel initial settings
          panel_start = wx.Panel(self)
          main_sizer = wx.BoxSizer(wx.VERTICAL)
          # Alias type selection
          text_start = wx.StaticText(panel_start, label="Please select the type of the new alias.")
          main_sizer.Add(text_start, 1, wx.ALL, 10)
          # Buttons
          buttons_sizer = wx.BoxSizer(wx.HORIZONTAL)
          main_sizer.Add(buttons_sizer, 1, wx.ALIGN_CENTER | wx.LEFT | wx.RIGHT | wx.BOTTOM, 10)
          # Main name button
          button_main_name = wx.Button(panel_start, label="Main Name")
          buttons_sizer.Add(button_main_name, 0, wx.ALIGN_CENTER | wx.RIGHT, 10)
          button_main_name.Bind(wx.EVT_BUTTON, self.main_name)
          # Common name button
          button_common_name = wx.Button(panel_start, label="Common Name")
          buttons_sizer.Add(button_common_name, 0, wx.ALIGN_CENTER)
          button_common_name.Bind(wx.EVT_BUTTON, self.common_name)
          # Panel final settings
          panel_start.SetSizer(main_sizer)
          main_sizer.SetSizeHints(self)
  
      @staticmethod
      def main_name(event):
          # Function for main name addition
          frame = AddMainName(None, title="New Main Name")
          frame.Centre()
          frame.Show()
  
      @staticmethod
      def common_name(event):
          # Function for common name addition
          frame = AddCommonName(None, title="New Common Name")
          frame.Centre()
          frame.Show()
  
  
  # GUI execution
  if __name__ == '__main__':
      app = wx.App()
      AliasGUI(None, title="Aliases Management GUI")
      app.MainLoop()
  </code></pre>