In a normal wxPython application, I start a thread before calling app.MainLoop(). The thread runs an infinite loop, listening on on database events (using Postgres LISTEN/NOTIFY). When there is an event, I update my wxPython main panel. Simple enough.
I also have an EXIT button bound to an exit handler. When I push the button, it generates an EVT_BUTTON event which in turn calls the exit handler, which tells the thread to terminate and destroys all windows. Everything terminates nicely.
But when I press the Windows ‘X’ button to close terminate, I know it should generate an EVT_CLOSE event which I can use to close everything.
But it does not; the application hangs.
From what I have read in the online sources, EVT_CLOSE is not generated because my thread is running. Kind of a catch-22! as far as I know, the only thing that would tell me that the application is closing in this case is the EVT_CLOSE event, which is not being issued.
Does anyone have a solution for this kind of thing?
EVT_CLOSE is generated anyway. The presence of the other thread is not a problem for EVT_CLOSE, I’ve practised it. The only point is that the application won’t terminate unless you join the other thread. Check if you bind (map) your on_lose function, or how do you call it.
In a normal wxPython application, I start a thread before calling
app.MainLoop(). The thread runs an infinite loop, listening on on
database events (using Postgres LISTEN/NOTIFY). When there is an event,
I update my wxPython main panel. Simple enough.
I also have an EXIT button bound to an exit handler. When I push the
button, it generates an EVT_BUTTON event which in turn calls the exit
handler, which tells the thread to terminate and destroys all windows.
Everything terminates nicely.
But when I press the Windows 'X' button to close terminate, I know it
should generate an EVT_CLOSE event which I can use to close everything.
But it does not; the application hangs.
From what I have read in the online sources, EVT_CLOSE is not generated
because my thread is running. Kind of a catch-22! as far as I know, the
only thing that would tell me that the application is closing in this
case is the EVT_CLOSE event, which is not being issued.
Does anyone have a solution for this kind of thing?
That did the job. I created a daemon thread and then issued a non-blocking join(1) call to ensure proper termination of both main application and its thread. Nikki later advised making a daemon thread, but I had already done that (so confirming that I did the right thing). Thanks to Michael and Nikki for your helpful advice.
···
On Monday, October 31, 2016 at 3:48:58 PM UTC+1, R. Miranda wrote:
In a normal wxPython application, I start a thread before calling app.MainLoop(). The thread runs an infinite loop, listening on on database events (using Postgres LISTEN/NOTIFY). When there is an event, I update my wxPython main panel. Simple enough.
I also have an EXIT button bound to an exit handler. When I push the button, it generates an EVT_BUTTON event which in turn calls the exit handler, which tells the thread to terminate and destroys all windows. Everything terminates nicely.
But when I press the Windows ‘X’ button to close terminate, I know it should generate an EVT_CLOSE event which I can use to close everything.
But it does not; the application hangs.
From what I have read in the online sources, EVT_CLOSE is not generated because my thread is running. Kind of a catch-22! as far as I know, the only thing that would tell me that the application is closing in this case is the EVT_CLOSE event, which is not being issued.
Does anyone have a solution for this kind of thing?
Acually, you’ve did it wrong, but in works at your side. In theory you have to do ONE of to options:
Make daemon thread, and then you don’t need join at all.
Make ordinary thread. Perhaps your thread is doing something in an endless loop. Make a thread-safe variable “stop_flag”. The thread should check it from time to time. When stop_flag is set to true, the function that is running in a thread must return. Finally
in the clean-up code
inside you main (GUI) thread, your do:
stop_flag=True
thread.join()
note: this is a blocking join.