Author: bugman Date: Wed Feb 4 15:32:44 2015 New Revision: 27511 URL: http://svn.gna.org/viewcvs/relax?rev=27511&view=rev Log: Large memory management improvement for the relax GUI wizards and GUI user functions. The pympler.muppy based memory management scripts in devel_scripts/memory_management for testing the GUI user function windows was showing that for each GUI user function call, 28 wx._core.BoxSizer elements were remaining in memory. This was traced back to the gui.wizards.wiz_objects.Wiz_window class, specifically the self._page_sizers and self._button_sizers lists storing wx.BoxSizer instances. The problem was that 16 page sizers and 16 button sizers were initialised each time for later use, however the add_page() method only added a small subset of these to the self._main_sizer wx.BoxSizer object. But the Destroy() method was only capable of destroying the wx.BoxSizer instances associated with another wxPython object. The fix was to add all page and button sizers to the self._main_sizer object upon initialisation. This will solve many memory issues in the GUI, especially in the GUI tests on Mac OS X systems causing 'memory error' or 'bus error' messages and on MS Windows due to 'USER Object' and 'GDI object' limitations. Modified: trunk/gui/wizards/wiz_objects.py Modified: trunk/gui/wizards/wiz_objects.py URL: http://svn.gna.org/viewcvs/relax/trunk/gui/wizards/wiz_objects.py?rev=27511&r1=27510&r2=27511&view=diff ============================================================================== --- trunk/gui/wizards/wiz_objects.py (original) +++ trunk/gui/wizards/wiz_objects.py Wed Feb 4 15:32:44 2015 @@ -432,11 +432,13 @@ # Append some Nones. self._pages.append(None) - # Initialise all box sizers for the wizard pages. + # Initialise all box sizers for the wizard pages, and store them. self._page_sizers.append(wx.BoxSizer(wx.VERTICAL)) - - # Initialise all box sizers for the buttons. + self._main_sizer.Add(self._page_sizers[i], 1, wx.ALL|wx.EXPAND, 0) + + # Initialise all box sizers for the buttons, and store them. self._button_sizers.append(wx.BoxSizer(wx.HORIZONTAL)) + self._page_sizers[i].Add(self._button_sizers[i], 0, wx.ALIGN_RIGHT|wx.ALL, 0) # Set all button flags. self._button_apply_flag.append(True) @@ -829,7 +831,7 @@ self.Close() # Loop over each page, destroying it and all its elements to avoid memory leaks. - for i in range(self._num_pages): + for i in range(len(self._buttons)): # Destroy the buttons. for name in self._buttons[i]: if hasattr(self._buttons[i][name], 'Destroy'): @@ -844,7 +846,7 @@ # Call the parent method to destroy the dialog. super(Wiz_window, self).DestroyChildren() super(Wiz_window, self).Destroy() - + def add_page(self, panel, apply_button=True, skip_button=False, exec_on_next=True, proceed_on_error=True, uf_flush=False): """Add a new page to the wizard. @@ -870,18 +872,12 @@ self._num_pages += 1 self._pages[index] = panel - # Store a new sizer for the page and its buttons. - self._main_sizer.Add(self._page_sizers[index], 1, wx.ALL|wx.EXPAND, 0) - # Add the sizer for the top half. top_sizer = wx.BoxSizer(wx.VERTICAL) self._page_sizers[index].Add(top_sizer, 1, wx.ALL|wx.EXPAND, 0) # Add the page to the top sizer. top_sizer.Add(panel, 1, wx.ALL|wx.EXPAND, 0) - - # Add the sizer for the wizard buttons. - self._page_sizers[index].Add(self._button_sizers[index], 0, wx.ALIGN_RIGHT|wx.ALL, 0) # Store the flags. self._button_apply_flag[index] = apply_button