[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