Hello,
encountered a funny bug when displaying a wx.SplashScreen and doing lengthy processing after displaying it. If the user clicks several times on the splash screen, it will make Windows7 display a dialog “Python.exe has stopped working”. If the user chooses “Close program” it will kill the app. If the user does nothing, the dialog goes away and the app starts to work normal.
It seems as if Windows would note that the click events on the splash screen are piling up and would decide to offer the user to kill the app (although it is still just loading).
For a minimal SCE see this stackoverflow post. I found a partial solution, but this will normally not be applicable to have wx.Yield()
sprinkled throughout the long running code.
I also did not try to start with threads, because in my case the whole GUI+matplotlib initialisation would take place there and I was not sure if that would be the right thing to do (to have the main GUI code to be executed in a thread.
nepix32 wrote:
encountered a funny bug when displaying a wx.SplashScreen and doing
lengthy processing after displaying it. If the user clicks several
times on the splash screen, it will make Windows7 display a dialog
"Python.exe has stopped working". If the user chooses "Close program"
it will kill the app. If the user does nothing, the dialog goes away
and the app starts to work normal.
It seems as if Windows would note that the click events on the splash
screen are piling up and would decide to offer the user to kill the
app (although it is still just loading).
That's EXACTLY what it did.
I also did not try to start with threads, because in my case the whole
GUI+matplotlib initialisation would take place there and I was not
sure if that would be the right thing to do (to have the main GUI code
to be executed in a thread.
That "stopped working" diagnosis is actually based on a timer. If the
message queue stays non-empty for a certain number of seconds, the app
is deemed to be non-responding. So, you need to get back to your
message loop once in a while. There are a couple of potential solutions
here.
As long as your initialization doesn't create any windows or perform any
drawing, you can certainly do it all in a separate thread. Or, you can
create the splash screen in a secondary thread, as long as you have a
message loop in that thread. Making it a modal dialog would do that.
Or, if you can split the initialization up into a number of discrete
steps, you can use Yield or CallAfter to make sure you get back to the
main loop.
···
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
As long as your initialization doesn’t create any windows or perform any
drawing, you can certainly do it all in a separate thread.
This actually worked best. Took a solution as described in the wxPython wiki on LongRunningTasks, see stackoverflow discussion.
Or, you can
create the splash screen in a secondary thread, as long as you have a
message loop in that thread. Making it a modal dialog would do that.
Tried to create a wx.SplashScreen in the secondary thread, but this did not work (complaining about not being in the main thread).
Tried splash.MakeModal()/splash.Show(), to no avail.
Nasty side effect is now that the splash goes out of scope and .Destroy()s itself when clicked.
Or, if you can split the initialization up into a number of discrete
steps, you can use Yield or CallAfter to make sure you get back to the
main loop.
This could possibly not be a solution in the general case, but would work in my app where I had this issue.
Anyway, thanks for the insight.