From 119352604d53ae893d95f76ed6bfc5a4cf85d9d3 2008-09-17 14:34:23
From: Gael Varoquaux <gael.varoquaux@normalesup.org>
Date: 2008-09-17 14:34:23
Subject: [PATCH] IPythonX: terminate the mainloop when exiting, to close the child windows
(eg pylab).

---

diff --git a/IPython/frontend/wx/ipythonx.py b/IPython/frontend/wx/ipythonx.py
index df81443..af7d322 100644
--- a/IPython/frontend/wx/ipythonx.py
+++ b/IPython/frontend/wx/ipythonx.py
@@ -80,6 +80,15 @@ class IPythonX(wx.Frame):
         self.SetSizer(self._sizer)
         self.SetAutoLayout(1)
         self.Show(True)
+        wx.EVT_CLOSE(self, self.on_close)
+
+        
+    def on_close(self, event):
+        """ Called on closing the windows. 
+            
+            Stops the event loop, to close all the child windows.
+        """
+        wx.CallAfter(wx.Exit)
 
 
 def main():
diff --git a/IPython/frontend/wx/wx_frontend.py b/IPython/frontend/wx/wx_frontend.py
index 97d1b24..d3ae507 100644
--- a/IPython/frontend/wx/wx_frontend.py
+++ b/IPython/frontend/wx/wx_frontend.py
@@ -275,6 +275,30 @@ class WxController(ConsoleWidget, PrefilterFrontEnd):
                                         milliseconds=100, oneShot=True)
 
 
+    #--------------------------------------------------------------------------
+    # LineFrontEnd interface 
+    #--------------------------------------------------------------------------
+ 
+    def execute(self, python_string, raw_string=None):
+        self._input_state = 'buffering'
+        self.CallTipCancel()
+        self._cursor = wx.BusyCursor()
+        if raw_string is None:
+            raw_string = python_string
+        end_line = self.current_prompt_line \
+                        + max(1,  len(raw_string.split('\n'))-1)
+        for i in range(self.current_prompt_line, end_line):
+            if i in self._markers:
+                self.MarkerDeleteHandle(self._markers[i])
+            self._markers[i] = self.MarkerAdd(i, _COMPLETE_BUFFER_MARKER)
+        # Use a callafter to update the display robustly under windows
+        def callback():
+            self.GotoPos(self.GetLength())
+            PrefilterFrontEnd.execute(self, python_string, 
+                                            raw_string=raw_string)
+        wx.CallAfter(callback)
+
+
     def execute_command(self, command, hidden=False):
         """ Execute a command, not only in the model, but also in the
             view.
@@ -307,29 +331,6 @@ class WxController(ConsoleWidget, PrefilterFrontEnd):
             return True
 
 
-    #--------------------------------------------------------------------------
-    # LineFrontEnd interface 
-    #--------------------------------------------------------------------------
- 
-    def execute(self, python_string, raw_string=None):
-        self._input_state = 'buffering'
-        self.CallTipCancel()
-        self._cursor = wx.BusyCursor()
-        if raw_string is None:
-            raw_string = python_string
-        end_line = self.current_prompt_line \
-                        + max(1,  len(raw_string.split('\n'))-1)
-        for i in range(self.current_prompt_line, end_line):
-            if i in self._markers:
-                self.MarkerDeleteHandle(self._markers[i])
-            self._markers[i] = self.MarkerAdd(i, _COMPLETE_BUFFER_MARKER)
-        # Use a callafter to update the display robustly under windows
-        def callback():
-            self.GotoPos(self.GetLength())
-            PrefilterFrontEnd.execute(self, python_string, 
-                                            raw_string=raw_string)
-        wx.CallAfter(callback)
-
     def save_output_hooks(self):    
         self.__old_raw_input = __builtin__.raw_input
         PrefilterFrontEnd.save_output_hooks(self)