multisash question

Hi -

I'm trying to setup a multisash app with the child class doing a
little cleanup when it is destroyed by the user.

The sample below is a simple testapp which shows the two methods I've
tried: EVT_CLOSE and overriding Destroy(). Neither works. I perused
the multisash.py source and confirmed that it is calling Destroy()
when the user clicks the red button so I'm confused.

Any help appreciated!

-Thanks!

-Todd

'''
Test wx.lib.multisash.
'''

import wx
import wx.lib.mixins.inspection as wxInspector

import wx.lib.multisash as wxSash

class EditControl(wx.Panel):
  '''
  EditControl class derived from wx.Panel.

  Just a blank panel for now for testing
  '''
  def __init__(self, parent):
    '''
    Instantiate the panel, initialize state variables.
    '''
    wx.Panel.__init__(self, parent, -1, name = 'EditControl',
                      style = wx.NO_BORDER)
    print "New EC created"
    self._getController(parent)

    # this isn't working... don't seem to be getting the event.
    self.Bind(wx.EVT_CLOSE, self.onCloseWindow)

  def _getController(self, parent):
    '''
    Find the EditPanel that hosts me, then add me to it's list.
    '''
    count = 0
    win = parent
    while not isinstance(win, EditPanel):
      print count, type(win)
      count += 1
      win = win.GetParent()
    print "controlling parent is", type(win), count
    self.cp = win
    self.cp._addEC(self)

  def onCloseWindow(self, event):
    '''
    Remove myself from my controller's list.
    '''
    print 'EditControl onCloseWindow'
    self.cp._delEC(self)

  def Destroy(self):
    '''
    Remove myself from my controller's list.
    '''
    # This isn't getting called either
    print 'EditControl Destroy'
    self.cp._delEC(self)
    wx.Panel.Destroy()

class EditPanel(wx.Panel):
  '''
  EditPanel class derived from wx.Panel.

  A panel with an EC or a multisash with EC(s)
  '''
  def __init__(self, parent, multiView = False):
    '''
    Build the panel, initialize state variables.
    '''
    wx.Panel.__init__(self, parent, name = 'EditPanel')
    self.eclist = []
    self.sizer = wx.BoxSizer(wx.VERTICAL)
    if multiView:
      self.ms = wxSash.MultiSash(self, -1)
      self.ms.SetDefaultChildClass(EditControl)
      self.sizer.Add(self.ms, 1, wx.ALL | wx.EXPAND, 0)
    else:
      self.ec = EditControl(self, text, doc)
      self.sizer.Add(self.ec, 1, wx.ALL | wx.EXPAND, 0)
    self.SetSizer(self.sizer)
    self.Layout()

  def _addEC(self, EC):
    '''
    Add a child EC to my list.
    '''
    self.eclist.append(EC)
    print self.eclist

  def _delEC(self, EC):
    '''
    Delete a child EC from my list.
    '''
    # todo:
    print self.eclist

class EditFrame(wx.Frame):
  '''
  Frame for the EditPanel class.
  '''
  def __init__(self, multiView = False):
    '''
    Create the custom frame and status bar.
    '''
    wx.Frame.__init__(self, None, -1, 'EditFrame', size = (640, 480))
    self.statusBar = wx.StatusBar(self, -1)
    self.statusBar.SetFieldsCount(2)
    self.SetStatusBar(self.statusBar)
    self.panel = EditPanel(self, multiView)
    self.Bind(wx.EVT_CLOSE, self.onCloseWindow)
    self.CenterOnScreen()

  def onCloseWindow(self, event):
    print 'EditFrame onCloseWindow'
    self.Destroy()

class EditTestApp(wx.App, wxInspector.InspectionMixin):
  '''
  Test application for the EditPanel class.
  '''
  def OnInit(self):
    '''
    Create the main window and insert the custom frame.
    '''
    self.Init() # Initialize the inspection tool
    self.Bind(wx.EVT_KEY_DOWN, self.onKeyPress)
    frame = EditFrame(True)
    self.SetTopWindow(frame)
    frame.Show(True)
    return True

  def onKeyPress(self, evt):
    '''
    Process key press events.
    '''
    if evt.AltDown() and evt.CmdDown():
      if evt.GetKeyCode() == ord('I'):
        # call the InspectionMixin key press handler
        self._OnKeyPress(evt)
    evt.Skip()

if __name__=='__main__':
  '''
  Run the test application class if directly executed.
  '''
  app = EditTestApp(0)
  app.MainLoop()

EVT_CLOSE is only sent for top-level windows (frames and dialogs.)

When the red button is clicked then I think it is calling Destroy on the MultiClient window, not yours. As for why your overridden Destroy is not being called when the client destroys its children, read this: OverridingMethods - wxPyWiki

You can probably do what you want with EVT_WINDOW_DESTROY.

···

On 3/26/10 1:08 PM, Todd wrote:

Hi -

I'm trying to setup a multisash app with the child class doing a
little cleanup when it is destroyed by the user.

The sample below is a simple testapp which shows the two methods I've
tried: EVT_CLOSE and overriding Destroy(). Neither works. I perused
the multisash.py source and confirmed that it is calling Destroy()
when the user clicks the red button so I'm confused.

--
Robin Dunn
Software Craftsman