[wxPython-users] Again closing frames and application

Werner F. Bruhin werner.bruhin at free.fr
Mon Oct 30 06:33:26 PST 2006


Hi Johannes,

Johannes Vetter wrote:

>Hello,
>
>I've got a problem regarding closing of frames and appliation too.
>Attached to this mail you'll find a small sample application to
>reproduce the situation.
>
>My application creates a number of frames (from xml).  When a frame gets
>closed it will be hidden only so the app can show it later again (if
>needed).  If the last frame has been hidden the application destroys all
>frames and so quits.  This works fine until the question dialog appears.
>
>Ok, when a frame gets hidden the app checks if there are pending
>(unsaved) changes.  If so, a dialog appears asking wether they should be
>saved or not.  After this dialog has been answered, the frame hides (and
>it gets destroyed) but the main loop will *not* be stopped.  If there is
>no such dialog (in our sample-code the text-entry is empty) the main
>loop gets terminated as expected.
>
>The sample application is quite simple.  If the text-entry widget is
>left empty, the frame is "clean", which means no dialog will appear on
>closing the frame (either by menu or via X-button).  If the text-entry
>widget is not empty, the dialog appears and the appication's main loop
>won't get terminated after closing the frame.
>
>If we uncomment the line "event.GetEventObject().Show()" in the method
>"OnCloseWindow", the main loop terminates as expected even if a dialog
>apears.
>
>Why do I need to add that Show() ?  Does it make sense, or is it a bug?
>  
>
For what it is worse, for me your sample closes correctly without having 
to use your work around.  (on Windows XP, Python 2.4 and wxPython 2.6.3.3

Werner

>Thanks for your help,
>
>Johannes
>
>
>  
>
>------------------------------------------------------------------------
>
>#!/usr/bin/python
># -*- coding: utf-8 -*-
># Closing frames and exiting the application
>
>import wx
>
># =============================================================================
># Sample frame class
># =============================================================================
>
>class MyFrame(wx.Frame):
>
>    def __init__(self):
>        wx.Frame.__init__(self, None, -1, "Testing ...")
>
>        self.CreateStatusBar()
>
>        mainmenu = wx.MenuBar()
>        menu = wx.Menu()
>        menu.Append(wx.ID_EXIT, 'E&xit\tCtrl+Q', 'Get the heck outta here!')
>        mainmenu.Append(menu, "&File")
>        self.SetMenuBar(mainmenu)
>
>        self.Bind(wx.EVT_MENU, self.OnExit, id=wx.ID_EXIT)
>        self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
>
>        sizer = wx.BoxSizer(wx.VERTICAL)
>        self.txt = wx.TextCtrl(self, -1)
>        sizer.Add(self.txt, 0, wx.EXPAND | wx.ALL, 10)
>
>        self.SetSizerAndFit(sizer)
>        self.txt.SetFocus()
>        self.Show()
>
>
>    # -------------------------------------------------------------------------
>
>    def OnCloseWindow(self, event):
>        """ wx.EVT_CLOSE handler """
>
>        print "OnCloseWindow"
>        if event.CanVeto():
>            print "CanVeto"
>            event.Veto()
>            self.deferred_close()
>        else:
>            print "No Veto allowed, so just do what has to be done"
>            # FIXME: if we uncomment the following line, everything works fine.
>            #        But why is it needed ?
>            # event.GetEventObject().Show()
>            event.Skip()
>
>
>    # -------------------------------------------------------------------------
>
>    def OnExit(self, event):
>        """ Event handler for wx.EVT_MENU (with wx.ID_EXIT) """
>
>        print "ON-EXIT called from Menu"
>        self.deferred_close()
>
>
>    # -------------------------------------------------------------------------
>
>    def deferred_close(self):
>        """ check wether the user has unsaved data ... """
>
>        print "DeferredClose: checking wether user has unsaved stuff ..."
>        if self.txt.GetValue() != '' and self.__ask() is None:
>            return
>
>        self._ui_close_()
>        self.maybe_exit()
>
>    # -------------------------------------------------------------------------
>
>    def maybe_exit(self):
>        """ If no other frames are open close the application """
>
>        print "Check if there are other windows open, otherwise exit!"
>        # Usually we would iterate over all frames of an application here, but
>        # for simplification we just close this one
>        self.Close(True)
>
>    # -------------------------------------------------------------------------
>
>    def _ui_close_(self):
>        """
>        'close' this frame.  Our application will only hide frames instead of
>        closing them, since it might reuse them later and re-instanciating is
>        not an option.
>        """
>
>        print "_ui_close_ will only hide this frame (for later reuse)"
>        self.Hide()
>
>
>    # -------------------------------------------------------------------------
>
>    def __ask(self):
>        """ helper method showing a simple question dialog """
>
>        dlg = wx.MessageDialog(self, 'Wanna save stuff?', 'A Question',
>                wx.YES_NO | wx.CANCEL)
>        try:
>            result = dlg.ShowModal()
>        finally:
>            dlg.Destroy()
>
>        if result in [wx.ID_YES, wx.ID_NO]:
>            return result == wx.ID_YES
>        else:
>            return None
>
>
># =============================================================================
>
>if __name__ == '__main__':
>    app = wx.PySimpleApp()
>    f = MyFrame()
>    app.MainLoop()
>    print "GONE!"
>  
>






More information about the wxpython-users mailing list