Application Not Terminating

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Application Not Terminating

Andrea Gavana-2
Hello NGs,

   I probably found where the problem resides. As it is a wxPython+Matplotlib
issue, I will send the mail to both newsgroups.
The reason why my application does not terminates correctly on Windows 2000
while it terminates correctly on Windows XP does not depend on Windows version,
but on Matplotlib. I am not 100% sure, because here I only have (at the
moment) Windows XP, but I found a difference between 2 Matplotlib installations
I have.
On XP, I have Matplotlib 0.73 prerelease (that WAS a prerelease 1 months
ago, nearly), while on Windows 2000 I have Matplotlib 0.74.
Well, I am using the WXAgg backend. By looking at backend_wx.py in 0.73pre
(XP), I see that lines 116-117 are commented. These lines are:

# wxapp = wxPySimpleApp()
# wxapp.SetExitOnFrameDelete(True)

While on Matplotlib 0.74 (2000) they are NOT commented. Well, in my app
I don't need to initialize the wx.App() when calling plot/figure/Matplotlib
things, because my app has ALREADY initialized the wx.App().
If I use Matplotlib (without wxPython) I will just add:

import wx
MyApp = wx.PySimpleApp()

Before using any Matplotlib command.
Is there a reason why these lines were commented on 0.73pre and now they
are not? Robin/John, could it be that the reason for which my application
does not return under Windows 2000?

Thanks to you all.

Andrea.

>[hidden email] wrote:
>> Hello NG,
>>
>>     It's incredible... after having found that my application correctly
>> terminates if I add the line:
>>
>> self.MyTaskBarIcon.Destroy()
>>
>> on Windows XP, I am UNABLE to terminate it on Windows 2000. The main
frame

>> is correctly destroyed, together with its children, but there is still
>something
>> alive that prevents Python to correctly finish and returning to me the
>control
>> of the DOS console.
>> The wxPython version is the same, the Python version is the same... the
>> only differences between the 2 PC is the Windows version (XP=work, 2000=don't
>> work) and the PC performances (XP=1GB RAM, 2000=528MB RAM).
>> I used Spy++ and its friends and, after my app terminates, on 2000 there
>> is still a window opened. This window has no class information, no particular
>> ID, only a size and position elements. There is no reason why the application
>> behavior should be different.
>> I don't even know which question I would formulate to you NG, it is a
pain
>> this continuous error-checking for a window/frame/panel that I didn't
create
>> and that wxPython thinks is still alive (only on Windows 2000).
>
>If you can create a small sample that shows the problem I can run it
>under the debugger to see if I can spot what's going on.
>
>--
>Robin Dunn
>Software Craftsman
>http://wxPython.org  Java give you jitters?  Relax with wxPython!




Reply | Threaded
Open this post in threaded view
|

Re: Application Not Terminating

Robin Dunn
[hidden email] wrote:

> On XP, I have Matplotlib 0.73 prerelease (that WAS a prerelease 1 months
> ago, nearly), while on Windows 2000 I have Matplotlib 0.74.
> Well, I am using the WXAgg backend. By looking at backend_wx.py in 0.73pre
> (XP), I see that lines 116-117 are commented. These lines are:
>
> # wxapp = wxPySimpleApp()
> # wxapp.SetExitOnFrameDelete(True)
>
> While on Matplotlib 0.74 (2000) they are NOT commented. Well, in my app
> I don't need to initialize the wx.App() when calling plot/figure/Matplotlib
> things, because my app has ALREADY initialized the wx.App().
> If I use Matplotlib (without wxPython) I will just add:
>
> import wx
> MyApp = wx.PySimpleApp()
>
> Before using any Matplotlib command.
> Is there a reason why these lines were commented on 0.73pre and now they
> are not? Robin/John, could it be that the reason for which my application
> does not return under Windows 2000?

Yes.  Having two app objects can certainly cause problems, although I
wouldn't have expected it to manifest this way.  Probably what is
happening is that when the spashscreen is closed it is being added to
the pending delete list but then the new app is being created and the
pending delete list is reinitialized and so the splash screen never gets
destroyed for real so the app's MainLoop keeps running waiting for it to
be destroyed.

To find out for sure you could try uncommenting those lines on your XP
box and see if you then have the same problem.

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



Reply | Threaded
Open this post in threaded view
|

Re: Application Not Terminating

Chris Barker - NOAA Federal

>> (XP), I see that lines 116-117 are commented. These lines are:
>>
>> # wxapp = wxPySimpleApp()
>> # wxapp.SetExitOnFrameDelete(True)

The wxApp should NOT be created here! However, if there seems to be a
reason that it has to be, perhaps these lines could be surrounded by a
check to see if there is already a wxApp running.

Robin, is there a call to do that? Maybe:

if not wxGetApp():
     wxapp = wxPySimpleApp()
     wxapp.SetExitOnFrameDelete(True)

I just tested this quickly, and wxGetApp() returns None before app
creation, and a wxApp instance after, which returns True, so it should work.

For that matter, maybe wx.PySimpleApp() should check itself, and never
create a duplicate app.

By the way, it really should be:

import wx

wx.PySimpleApp()

etc.

Maybe I'll get around to cleaning up that code some day!

-Chris


--
Christopher Barker, Ph.D.
Oceanographer
                                     
NOAA/OR&R/HAZMAT         (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

[hidden email]


Reply | Threaded
Open this post in threaded view
|

RE: [Matplotlib-users] Re: Application Not Terminating

Andrea Gavana-2
In reply to this post by Robin Dunn
Hello NGs,

>[hidden email] wrote:
>
>> On XP, I have Matplotlib 0.73 prerelease (that WAS a prerelease 1 months
>> ago, nearly), while on Windows 2000 I have Matplotlib 0.74.
>> Well, I am using the WXAgg backend. By looking at backend_wx.py in 0.73pre
>> (XP), I see that lines 116-117 are commented. These lines are:
>>
>> # wxapp = wxPySimpleApp()
>> # wxapp.SetExitOnFrameDelete(True)
>>
>Yes.  Having two app objects can certainly cause problems, although I
>wouldn't have expected it to manifest this way.  Probably what is
>happening is that when the spashscreen is closed it is being added to
>the pending delete list but then the new app is being created and the
>pending delete list is reinitialized and so the splash screen never gets
>
>destroyed for real so the app's MainLoop keeps running waiting for it to
>
>be destroyed.
>
>To find out for sure you could try uncommenting those lines on your XP

>box and see if you then have the same problem.
>

Ok Robin, I've done what you suggested: on my XP box I uncommented the 2
lines, and the application does NOT returns. So I found where the problem
resides. It is not a wxPython nor a Windows issue, but a Matplotlib one.

Now I will probably leave them commented or I will add the Chris patch (checking
if a wx.App is already started or not).
Finding this inconsistency in Matplotlib was a 2 weeks nightmare.
Thanks for all your suggestions, NGs.

Andrea.



Reply | Threaded
Open this post in threaded view
|

Re: [Matplotlib-users] Re: Application Not Terminating

John Hunter-8

OK, I spent some time looking at this morning and think I have a fix
that works for matplotlib wx API users as well as pylab users.  For
the record, a little background.

The module matplotlib.backends.backend_wx contains all the classes to
enable matplotlib to be embedded in a wx application.  There are two
modes this module is used in: application developers who want to
control the wx windows, panels, frames, etc, themselves, and pylab
users who want a matlab like environment in which all the figure
window, creation, etc, is managed for them.

To support the latter, all the matplotlib GUI backends are required to
define two functions

  new_figure_manager - creates a new wxFrame
  show               - realizes/shows all frames

Jeremy O'Donoghue, who wrote the wx backend, and latter Matt Newville
who has been helping maintain it of late, tried putting the wxapp
instantiation in the show function, but this caused a segfault on some
platforms with some versions of wxpython (win32 with 2.4.x).  We never
figured out the root cause of this since often times the person
developing/maintaining wx didn't have access to the buggy combination
of platform + version.  So we left wxapp creation at the module level
which was ugly, hacky, and buggy, but at least it didn't seg fault.

Today I spent some time tracking down where and why the segfault was
occurring, and it was

  new_figure_manager -> FigureFrameWx -> wxPanel.__init__

The call to wxPanel.__init__ trigged the segfault.

It appears the cause of this problem is that the wxapp must be created
before the wxPanel is init'ed.  The solution is to put the wxapp
creation in new_figure_manager, not show, so that the app will be
created before the wxpanel.  This appears to work.  Here is what I am
currently doing


wxapp = None  # module level

def new_figure_manager(num, *args, **kwargs):
    global wxapp
    if wxapp is None:
        wxapp = wx.PySimpleApp()
        wxapp.SetExitOnFrameDelete(True)
    ...snipsnip...



def show():
    ...snipsnip...
    if show._needmain and not matplotlib.is_interactive():
        if wxapp is not None: wxapp.MainLoop()
        show._needmain = False        


And this seems to work for pylab and wx apps.  Since apps will never
call new_figure_manager or show, there should be no problem


If there is a better / more elegant / more wxlike way to do this, let
me know.

Thanks,
JDH


Reply | Threaded
Open this post in threaded view
|

Re: [Matplotlib-users] Re: Application Not Terminating

Matt Newville
John,

> It appears the cause of this problem is that the wxapp must be
> created before the wxPanel is init'ed.  The solution is to put
> the wxapp creation in new_figure_manager, not show, so that
> the app will be created before the wxpanel.  This appears to
> work.  Here is what I am currently doing
 
Yep, I think this is exactly the problem (though I could never
reproduce it), and, like you say, creating wxapp in
new_figure_manager() sounds like the right solution to me.  I
think this was part of the discussion with Marcin W. a month
ago, no??  Anyway, in backend_tkagg (the closest analogy I'm
familar with), Tk.Tk() is created in new_figure_manager.  It
seems that with other windowing systems, it's ok to create the
mainApp (ie, who will run the event loop) if needed in show()???
Perhaps it would make sense to have this be more uniform across
the different backends?

Thanks,

--Matt



Reply | Threaded
Open this post in threaded view
|

Re: Application Not Terminating

Robin Dunn
In reply to this post by Chris Barker - NOAA Federal
Chris Barker wrote:

>
>>> (XP), I see that lines 116-117 are commented. These lines are:
>>>
>>> # wxapp = wxPySimpleApp()
>>> # wxapp.SetExitOnFrameDelete(True)
>
>
> The wxApp should NOT be created here! However, if there seems to be a
> reason that it has to be, perhaps these lines could be surrounded by a
> check to see if there is already a wxApp running.
>
> Robin, is there a call to do that? Maybe:
>
> if not wxGetApp():

Yep, wx.GetApp is the best way to detect if the app has been created yet.

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



Reply | Threaded
Open this post in threaded view
|

Re: Re: [Matplotlib-users] Re: [wxPython-users] Application Not Terminating

Robin Dunn
In reply to this post by John Hunter-8
John Hunter wrote:

> wxapp = None  # module level
>
> def new_figure_manager(num, *args, **kwargs):
>     global wxapp
>     if wxapp is None:
>         wxapp = wx.PySimpleApp()
>         wxapp.SetExitOnFrameDelete(True)
>     ...snipsnip...
>
>
>
> def show():
>     ...snipsnip...
>     if show._needmain and not matplotlib.is_interactive():
>         if wxapp is not None: wxapp.MainLoop()
>         show._needmain = False        
>
>
> And this seems to work for pylab and wx apps.  Since apps will never
> call new_figure_manager or show, there should be no problem
>
>
> If there is a better / more elegant / more wxlike way to do this, let
> me know.

You should check wx.GetApp() to ensure that the app hasn't already been
created in some other module.

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