Controlling the Exit from an application

Hello,

This seems like a trivial question, but I have been playing with this for awhile now. Currently I have a frame which is controlled by the aui manager. When I click on the X in the upper right hand corner of the window I want to have the user verify a few things before the application quits. I am using the wx.EVT_CLOSE and have tried the wx.EVT_WINDOW_DESTROY to route to a custom method to handle the event.

I can route the event to my function in which I prompt the user with some MessageDialogs. This is where the problem occurs. After a few seconds I get a prompt that my application is no longer responsive, and then quits. I tried simply detected the event and trying to skip it but what it comes down to is that when I click the X in the upper right hand corner it kills the program. So my question is, what is the proper way to handle this kind of closing, in such a way that I can cancel it if I don’t want to exit?

I have attached the function I call when I detect a wx.EVT_CLOSE.

def OnClose(self, evt):

dlg = wx.MessageDialog(None, msg, "Save File?", style=wx.YES_NO | wx.CANCEL | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP)

           
            selection = dlg.ShowModal()
           
            if selection == wx.ID_YES:
                self.saveDialog(pgIndex,2)
            elif selection == wx.ID_CANCEL:

                evt.Skip()
               
            dlg.Destroy()
   
    self.aui_mgr.UnInit()
    del self.aui_mgr
    self.Destroy()

Sorry, I sent that last one incomplete. Please ignore the section of code I sent and refer to this one.

self.Bind(wx.EVT_CLOSE, self.OnClose)
.
.
.
def OnClose(self, evt):

            dlg = wx.MessageDialog(None, msg, "Save File?", style=wx.YES_NO | wx.CANCEL | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP)
           
            selection = dlg.ShowModal()
           

            if selection == wx.ID_YES:
                self.saveDialog(pgIndex,2)
            elif selection == wx.ID_CANCEL:
                evt.Skip()
               
            dlg.Destroy()

   
            self.aui_mgr.UnInit()
            del self.aui_mgr
            self.Destroy()

Thanks
Scott

···

On Wed, Aug 20, 2008 at 3:27 PM, Scott Hall smhall316@gmail.com wrote:

Hello,

This seems like a trivial question, but I have been playing with this for awhile now. Currently I have a frame which is controlled by the aui manager. When I click on the X in the upper right hand corner of the window I want to have the user verify a few things before the application quits. I am using the wx.EVT_CLOSE and have tried the wx.EVT_WINDOW_DESTROY to route to a custom method to handle the event.

I can route the event to my function in which I prompt the user with some MessageDialogs. This is where the problem occurs. After a few seconds I get a prompt that my application is no longer responsive, and then quits. I tried simply detected the event and trying to skip it but what it comes down to is that when I click the X in the upper right hand corner it kills the program. So my question is, what is the proper way to handle this kind of closing, in such a way that I can cancel it if I don’t want to exit?

I have attached the function I call when I detect a wx.EVT_CLOSE.

def OnClose(self, evt):

dlg = wx.MessageDialog(None, msg, "Save File?", style=wx.YES_NO | wx.CANCEL | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP)


           
            selection = dlg.ShowModal()
           
            if selection == wx.ID_YES:
                self.saveDialog(pgIndex,2)
            elif selection == wx.ID_CANCEL:


                evt.Skip()
               
            dlg.Destroy()
   
    self.aui_mgr.UnInit()
    del self.aui_mgr
    self.Destroy()

Scott Hall wrote:

Sorry, I sent that last one incomplete. Please ignore the section of code I sent and refer to this one.

   self.Bind(wx.EVT_CLOSE, self.OnClose)
   .
    def OnClose(self, evt):
                dlg = wx.MessageDialog(None, msg, "Save File?", style=wx.YES_NO | wx.CANCEL | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP)
                               selection = dlg.ShowModal()
                               if selection == wx.ID_YES:
                    self.saveDialog(pgIndex,2)
                elif selection == wx.ID_CANCEL:
                    evt.Skip()
                                   dlg.Destroy()
                       self.aui_mgr.UnInit()
                del self.aui_mgr
                self.Destroy()

Thanks
Scott

    Hello,

    This seems like a trivial question, but I have been playing with
    this for awhile now. Currently I have a frame which is controlled
    by the aui manager. When I click on the X in the upper right hand
    corner of the window I want to have the user verify a few things
    before the application quits. I am using the wx.EVT_CLOSE and
    have tried the wx.EVT_WINDOW_DESTROY to route to a custom method
    to handle the event.

    I can route the event to my function in which I prompt the user
    with some MessageDialogs. This is where the problem occurs. After a few seconds I get a prompt that my application is no
    longer responsive, and then quits. I tried simply detected the
    event and trying to skip it but what it comes down to is that when
    I click the X in the upper right hand corner it kills the
    program. So my question is, what is the proper way to handle this
    kind of closing, in such a way that I can cancel it if I don't
    want to exit?

    I have attached the function I call when I detect a wx.EVT_CLOSE.

        def OnClose(self, evt):

        dlg = wx.MessageDialog(None, msg, "Save File?",
    style=wx.YES_NO | wx.CANCEL | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP)
                                       selection = dlg.ShowModal()
                                       if selection == wx.ID_YES:
                        self.saveDialog(pgIndex,2)
                    elif selection == wx.ID_CANCEL:
                        evt.Skip()
                                           dlg.Destroy()
                       self.aui_mgr.UnInit()
            del self.aui_mgr
            self.Destroy()

Hi Scott,

I may be completely missing something here, but you only want the application to close if the user presses the dialog's "Yes" button, correct? If so, then I don't think you want to call self.Destroy() no matter which button is pushed. Instead, I think the following makes more sense:

<code>

def OnClose(self, evt):

    dlg = wx.MessageDialog(None, msg, "Save File?", style=wx.YES_NO | wx.CANCEL | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP)
                  selection = dlg.ShowModal()
      if selection == wx.ID_YES:
        self.saveDialog(pgIndex,2) self.aui_mgr.UnInit()
        del self.aui_mgr
        self.Destroy()
    elif selection == wx.ID_CANCEL:
        evt.Skip()
          dlg.Destroy()
      </code>

You can try it anyway...

···

On Wed, Aug 20, 2008 at 3:27 PM, Scott Hall <smhall316@gmail.com > <mailto:smhall316@gmail.com>> wrote:

-------------------
Mike Driscoll

Blog: http://blog.pythonlibrary.org
Python Extension Building Network: http://www.pythonlibrary.org

Mike Driscoll wrote:

Scott Hall wrote:

Sorry, I sent that last one incomplete. Please ignore the section of code I sent and refer to this one.

   self.Bind(wx.EVT_CLOSE, self.OnClose)
   .
    def OnClose(self, evt):
                dlg = wx.MessageDialog(None, msg, "Save File?", style=wx.YES_NO | wx.CANCEL | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP)
                               selection = dlg.ShowModal()
                               if selection == wx.ID_YES:

I may be completely missing something here, but you only want the application to close if the user presses the dialog's "Yes" button, correct? If so, then I don't think you want to call self.Destroy() no matter which button is pushed. Instead, I think the following makes more sense:

<code>

def OnClose(self, evt):

   dlg = wx.MessageDialog(None, msg, "Save File?", style=wx.YES_NO | wx.CANCEL | wx.ICON_EXCLAMATION | wx.STAY_ON_TOP)
                selection = dlg.ShowModal()
    if selection == wx.ID_YES:
       self.saveDialog(pgIndex,2) self.aui_mgr.UnInit()
       del self.aui_mgr
       self.Destroy()
   elif selection == wx.ID_CANCEL:
       evt.Skip()
        dlg.Destroy()
     </code>

The evt.Skip will cause the default EVT_CLOSE handler to be called, which is going to call Destroy. So if you don't want the frame to be closed then don't call Skip and don't call Destroy.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!