I’m working on PythonTurtle, which is an interactive “Learn Python” program with an embedded interpreter.
When I type the Python interpreter’s exit() command I want to shut down the application. This seems to be easier said than done. I’ve tried:
raise SystemExit(), which does nothing (seems to be caught by wxPython)
os._exit(0), the brute force way, makes the application window hang (showing an hour glass)
wx.Abort(), which behaves the same way as os._exit(0)
<xwFrame>.Close(force=True), which does nothing (though returning True)
post a wx.ID_EXIT event à la wx.PostEvent(...), which you can see in PR #133 on GitHub.
All attempts were unsuccessful.
Interestingly, I’ve found solutions mentioning wxFrame.Close and wxFrame.Destroyon StackOverflow, but none of them work for me.
As an alternative, I thought about firing the event that mimics the user action of selecting “File > Exit”, even though that feels like a cumbersome workaround. However, I’d need a similar thing for displaying a help screen, which should happen when the user types help() in the Python interpreter: Calling the show_help() method directly that is bound to the button produces an exception as if some attributes were lost on the frame object.
The code is all public and for the two problems there is an isolated pull request.
What do I have to do to implement the wanted behavior?
When I type the Python interpreter’s exit() command I want to shut down the application. This seems to be easier said than done. I’ve tried:
…
Interestingly, I’ve found solutions mentioning wxFrame.Close and wxFrame.Destroyon StackOverflow, but none of them work for me.
When the primary window is closed, the application exits. That’s how wxWindows is designed. Is it possible the window you’re triggering is not the applications “primary” window?
When I type the Python interpreter’s exit() command I want to shut down the application. This seems to be easier said than done. I’ve tried:
…
Interestingly, I’ve found solutions mentioning wxFrame.Close and wxFrame.Destroy
on StackOverflow, but none of them work for me.
When the primary window is closed, the application exits. That’s how wxWindows is designed. Is it possible the window you’re triggering is not the applications “primary” window?
—
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
I’m working on PythonTurtle, which is an interactive “Learn Python” program with an embedded interpreter.
When I type the Python interpreter’s exit() command I want to shut down the application. This seems to be easier said than done. I’ve tried:
raise SystemExit(), which does nothing (seems to be caught by wxPython)
os._exit(0), the brute force way, makes the application window hang (showing an hour glass)
wx.Abort(), which behaves the same way as os._exit(0)
<xwFrame>.Close(force=True), which does nothing (though returning True)
post a wx.ID_EXIT event à la wx.PostEvent(...), which you can see in PR #133 on GitHub.
All attempts were unsuccessful.
Interestingly, I’ve found solutions mentioning wxFrame.Close and wxFrame.Destroyon StackOverflow, but none of them work for me.
As an alternative, I thought about firing the event that mimics the user action of selecting “File > Exit”, even though that feels like a cumbersome workaround. However, I’d need a similar thing for displaying a help screen, which should happen when the user types help() in the Python interpreter: Calling the show_help() method directly that is bound to the button produces an exception as if some attributes were lost on the frame object.
The code is all public and for the two problems there is an isolated pull request.
What do I have to do to implement the wanted behavior?
Thanks in advance for any hints, Peter
I think you need to replace builtins.exit (and builtins.quit) in your embedded instance of the Interpreter with function that destroy the main window. Specifically, you probably want to put your custom functions for “exit”, “quit”, and maybe “help” and “license” in the locals dict when creating the
Thanks for pointing out that there is also quit()!
Peter
···
Am Sonntag, 31. März 2019 20:59:39 UTC+2 schrieb Matt Newville:
Hi Peter,
I think you need to replace builtins.exit (and builtins.quit) in your embedded instance of the Interpreter with function that destroy the main window. Specifically, you probably want to put your custom functions for “exit”, “quit”, and maybe “help” and “license” in the locals dict when creating the
I’ve tried the code and it actually does … nothing.
Maybe the TopWindow is not the actual top frame we’re seeing. I’m not sure. There is really only a single frame, hmm. Any idea how I can troubleshoot this?
When I add thisapp.Destroy() after the instructions you suggest I get an interesting behavior: The application window doesn’t close, but at the next time I call the function wx.GetApp() returns None. So, “something” happened, but it wasn’t “shutting down the application”. Hmmm…
Peter
···
Am Sonntag, 31. März 2019 20:52:02 UTC+2 schrieb Gadget Steve:
Try:
theapp = wx.GetApp()
theapp.SetExitOnFrameDelete(True)
theapp.TopWindow.Close()
(This should call any cleaning up that closing the top window would normally do)!
When I type the Python interpreter’s exit() command I want to shut down the application. This seems to be easier said than done. I’ve tried:
…
Interestingly, I’ve found solutions mentioning wxFrame.Close and wxFrame.Destroy
on StackOverflow, but none of them work for me.
When the primary window is closed, the application exits. That’s how wxWindows is designed. Is it possible the window you’re triggering is not the applications “primary” window?
—
Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.
–
You received this message because you are subscribed to the Google Groups “wxPython-users” group.
To unsubscribe from this group and stop receiving emails from it, send an email to wxpytho...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
I figured this behavior may all be related to the fact that we’re using multiprocessing. And this doesn’t play nicely, or at least not intuitively straight-forward, with wxPython.
Is that an information that can help getting my implementation ironed out correctly?
Peter
···
Am Sonntag, 31. März 2019 22:22:47 UTC+2 schrieb Peter Bittner:
Thanks Steve,
I’ve tried the code and it actually does … nothing.
Maybe the TopWindow is not the actual top frame we’re seeing. I’m not sure. There is really only a single frame, hmm. Any idea how I can troubleshoot this?
When I add thisapp.Destroy() after the instructions you suggest I get an interesting behavior: The application window doesn’t close, but at the next time I call the function wx.GetApp() returns None. So, “something” happened, but it wasn’t “shutting down the application”. Hmmm…
What I do in my multiprocessing application is to keep track of all of the PIDs and have an OnExit handler terminate them all, (and wait a short time for them to finish), before exit.
Steve
On Behalf Of Peter Bittner
···
I figured this behavior may all be related to the fact that we’re using
multiprocessing. And this
doesn’t play nicely, or at least not intuitively straight-forward, with wxPython.
Is that an information that can help getting my implementation ironed out correctly?
Peter
Am Sonntag, 31. März 2019 22:22:47 UTC+2 schrieb Peter Bittner:
Thanks Steve,
I’ve tried the code and it actually does … nothing.
Maybe the TopWindow is not the actual top frame we’re seeing. I’m not sure. There is really only a single frame, hmm. Any idea how I can troubleshoot this?
When I add thisapp.Destroy() after the instructions you suggest I get an interesting behavior: The application window doesn’t close, but at the next time I call the function wx.GetApp() returns None. So,
“something” happened, but it wasn’t “shutting down the application”. Hmmm…
that sounds like a plan. How do you keep track of the PIDs? Can you give an example (as in code)?
Imagine you have a parent that forks off a child, and the child now invokes wx.Exit(). That makes the child process die. The parent windows (a wx.Frame) is still responsive, and I can operated the menu to end the application. – How can I, instead, make the parent process die? Or ask it to kill itself.
Peter
···
Am Montag, 1. April 2019 00:17:30 UTC+2 schrieb Gadget Steve:
Peter,
What I do in my multiprocessing application is to keep track of all of the PIDs and have an OnExit handler terminate them all, (and wait a short time for them to finish), before exit.
As it stands the problem is that I have a child process (the Python interpreter in the application window) that asks the parent process (the parent wx.Frame) to close itself, which it probably can honor for some reason, maybe related to the fact that the child is making the request.
What if I post an event that mimics the user going to “File > Exit” in the application window (the wx.MenuBar in the parent wx.Frame). How can I do that?
I would need to do the same operation for opening the help screen too, anyway. Simply calling self.parent_window.show_help() doesn’t work without an Exception later down the line.
Peter
···
Am Montag, 1. April 2019 01:10:49 UTC+2 schrieb Peter Bittner:
Steve,
that sounds like a plan. How do you keep track of the PIDs? Can you give an example (as in code)?
Imagine you have a parent that forks off a child, and the child now invokes wx.Exit(). That makes the child process die. The parent windows (a wx.Frame) is still responsive, and I can operated the menu to end the application. – How can I, instead, make the parent process die? Or ask it to kill itself.
Peter
Am Montag, 1. April 2019 00:17:30 UTC+2 schrieb Gadget Steve:
Peter,
What I do in my multiprocessing application is to keep track of all of the PIDs and have an OnExit handler terminate them all, (and wait a short time for them to finish), before exit.
I can’t post the actual code that I use in my work for obvious reasons but basically, (exact details vary on how the subprocesses are launched):
in init(self) of the top level process
self.subprocesses =
in all of the start subprocess methods
self.subprocesses.append(new_process_pid) # All of the methods of launching subprocesses have some mechanism for getting the PID
in the call back from the subprocess,
this is where you could get clever!
self.subprocesses.remove(pid) # The callback gets the PID as a parameter
in the top level process OnExit method
for pid in self.subprocesses:
call the halt/stop/exit for that pid
Re you help problem it sounds like you are calling the self.parent_window.show_help() without an event, (or dummy event), or the event is lacking some detail possibly the parent window that is relied on later. What exactly is the exception it should show what is missing?
Hope that is some help.
Steve
On Behalf Of Peter Bittner
···
As it stands the problem is that I have a child process (the Python interpreter in the application window) that asks the parent process (the parent wx.Frame) to close itself, which it probably can honor for some
reason, maybe related to the fact that the child is making the request.
What if I post an event that mimics the user going to “File > Exit” in the application window (the
wx.MenuBar in the parent wx.Frame). How can I do that?
I would need to do the same operation for
opening the help screen too, anyway. Simply calling self.parent_window.show_help() doesn’t work without an Exception later down the line.
Peter
Am Montag, 1. April 2019 01:10:49 UTC+2 schrieb Peter Bittner:
Steve,
that sounds like a plan. How do you keep track of the PIDs? Can you give an example (as in code)?
Imagine you have a parent that forks off a child, and the child now invokes wx.Exit(). That makes the child process die. The parent windows (a wx.Frame) is still responsive, and I can operated the menu to
end the application. – How can I, instead, make the parent process die? Or ask it to kill itself.
Peter
Am Montag, 1. April 2019 00:17:30 UTC+2 schrieb Gadget Steve:
Peter,
What I do in my multiprocessing application is to keep track of all of the PIDs and have an OnExit handler terminate them all, (and wait a short time for them to finish), before exit.
All the window handles, event loop, and all other UI-related elements are NOT inherited by the child process. (There may be an object but it is not connected to the original UI element.) It’s not completely clear from your descriptions thus far if you are aware of that or not. In case you’re not, you can not expect any wx thing that crosses the process boundary to work as if they were in the same process. In other words, if the parent process needs the UI elements in the child process to do something then you can’t just use the original object in the parent process to do it. Instead you need a non-UI way to send a message to the child and then have the child do it to itself. The multiprocessing module has a few ways to do that, and there are others too. Or if all you need to do is tell the child to terminate then using kill as Steve suggests is okay too, although you may want to have the child process catch those signals so they can shut down cleanly (flushing and closing files, etc.) if not doing so could cause problems.
···
On Sunday, March 31, 2019 at 2:52:26 PM UTC-7, Peter Bittner wrote:
I figured this behavior may all be related to the fact that we’re using multiprocessing. And this doesn’t play nicely, or at least not intuitively straight-forward, with wxPython.
Is that an information that can help getting my implementation ironed out correctly?