When wx.App is killed

Hello,

I'm having a simple wx application that looks like this:

···

---------------------------------------------------------
class App(wx.App):
     def __init__(self, redirect=True, filename=None)
         wx.App.__init__(self, redirect, filename)

         ...
     def OnInit(self):
         myFrame = StartFrame()
         myFrame.Show()

     ...

class StartFrame(wx.Frame):
     def __init__(self):
         wx.Frame.__init__(self, None, -1, "My title")
         self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
         ...
     def OnCloseWindow(self, event):
         print 'Closing the window'

if __name__ == "__main__":
     app = App(redirect=False)
     app.MainLoop ()
-------------------------------------------------------

Closing the application works fine when, for example, clicking on the
upper right red cross of the frame.
Now, what if the application is closed by something that comes from
outside the application ? Example, through the Task Manager (in
Windows). Another example: I start the application in a cmd window
(python myApplication.py) and than I type 'ctrl C' (in the cmd
window).
I'd like that what's done in OnCloseWindow() is also run in this case.
I
tried to add OnExit and/or ExitMainLoop methods to my App class, but
nothing happens, and frankly I have trouble to understand how this
all
works. Also, there is the wx.EVT_QUERY_END_SESSION event that could
be
used (?), but I guess it doesn't apply in this case.

Thanks.

Raphael

Hi,

Closing the application works fine when, for example, clicking on the
upper right red cross of the frame.
Now, what if the application is closed by something that comes from
outside the application ? Example, through the Task Manager (in
Windows). Another example: I start the application in a cmd window
(python myApplication.py) and than I type 'ctrl C' (in the cmd
window).
I'd like that what's done in OnCloseWindow() is also run in this case.
I
tried to add OnExit and/or ExitMainLoop methods to my App class, but
nothing happens, and frankly I have trouble to understand how this
all
works. Also, there is the wx.EVT_QUERY_END_SESSION event that could
be
used (?), but I guess it doesn't apply in this case.

You can setup a termination handler, prior to starting the main loop
to get a callback when the OS tries to close your application.

Not sure what OS(es) your on:

On Linux / OSX:

@see: signal.signal and signal.SIGTERM from the python stdlib

On Windows:

@see win32api.SetConsoleCtrlHandler

Cody

···

On Wed, Jun 22, 2011 at 4:33 AM, rapmay <maygeo@netplus.ch> wrote:

Try adding 'self.Skip' to the end of 'OnClosewindow'. The App needs
to go kill the mainloop.

regards,
Rathaus

···

On Jun 22, 2:33 am, rapmay <may...@netplus.ch> wrote:

Hello,

I'm having a simple wx application that looks like this:

---------------------------------------------------------
class App(wx.App):
def __init__(self, redirect=True, filename=None)
wx.App.__init__(self, redirect, filename)

     \.\.\.
 def OnInit\(self\):
     myFrame = StartFrame\(\)
     myFrame\.Show\(\)

 \.\.\.

class StartFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "My title")
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
...
def OnCloseWindow(self, event):
print 'Closing the window'

if __name__ == "__main__":
app = App(redirect=False)
app.MainLoop ()
-------------------------------------------------------

Closing the application works fine when, for example, clicking on the
upper right red cross of the frame.
Now, what if the application is closed by something that comes from
outside the application ? Example, through the Task Manager (in
Windows). Another example: I start the application in a cmd window
(python myApplication.py) and than I type 'ctrl C' (in the cmd
window).
I'd like that what's done in OnCloseWindow() is also run in this case.
I
tried to add OnExit and/or ExitMainLoop methods to my App class, but
nothing happens, and frankly I have trouble to understand how this
all
works. Also, there is the wx.EVT_QUERY_END_SESSION event that could
be
used (?), but I guess it doesn't apply in this case.

Thanks.

Raphael

RapMay,
Disregard my previous message.

you need to Bind wx.EVT_CLOSE to say self.OnFrameClose.
Then in def OnFrameClose add one line event.Skip().

  self.Bind(wx.EVT_CLOSE, self.OnFrameClose)

  def OnFrameClose(self, event):
       event.Skip()

You can have other code before the event.Skip() but you must have the
event.Skip() which will then kill the app.MainLoop.

regards,
Rathaus

···

On Jun 22, 2:33 am, rapmay <may...@netplus.ch> wrote:

Hello,

I'm having a simple wx application that looks like this:

---------------------------------------------------------
class App(wx.App):
def __init__(self, redirect=True, filename=None)
wx.App.__init__(self, redirect, filename)

     \.\.\.
 def OnInit\(self\):
     myFrame = StartFrame\(\)
     myFrame\.Show\(\)

 \.\.\.

class StartFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, -1, "My title")
self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
...
def OnCloseWindow(self, event):
print 'Closing the window'

if __name__ == "__main__":
app = App(redirect=False)
app.MainLoop ()
-------------------------------------------------------

Closing the application works fine when, for example, clicking on the
upper right red cross of the frame.
Now, what if the application is closed by something that comes from
outside the application ? Example, through the Task Manager (in
Windows). Another example: I start the application in a cmd window
(python myApplication.py) and than I type 'ctrl C' (in the cmd
window).
I'd like that what's done in OnCloseWindow() is also run in this case.
I
tried to add OnExit and/or ExitMainLoop methods to my App class, but
nothing happens, and frankly I have trouble to understand how this
all
works. Also, there is the wx.EVT_QUERY_END_SESSION event that could
be
used (?), but I guess it doesn't apply in this case.

Thanks.

Raphael

That doesn’t do it on MS Windows. The python process is killed by the OS and so OnCloseWindow() is never reached from outside the app

Cody is right - the only way in MSW to implement a <ctrl_C> handler is to call win32api.SetConsoleCtrlHandle and to translate the attached exit handler function, ConsoleCtrlHandler(), into a python function. Or by creating a python C extension dll by compiling the existing C code and creating a python wrapper for it. Either method produces a callable Python function.

Ray

ExitHandler_MSW.C (1.51 KB)

ExitHandler.py (870 Bytes)

Thanks Cody and Ray,

Yep, 'win32api.SetConsoleCtrlHandler' is the solution.
Found a piece of useful code in How To Catch “Kill” Events with Python | daniel's devel blog
It doesn't work when the process is killed by the task manager though, but nicely when using <ctrl_C>.

Raphael

···

On 2011-06-23 23:06, Ray Pasco wrote:

That doesn't do it on MS Windows. The python process is killed by the OS and so OnCloseWindow() is never reached from outside the app

Cody is right - the only way in MSW to implement a <ctrl_C> handler is to call win32api.SetConsoleCtrlHandle and to translate the attached exit handler function, ConsoleCtrlHandler(), into a python function. Or by creating a python C extension dll by compiling the existing C code and creating a python wrapper for it. Either method produces a callable Python function.

Ray

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en