On Fri, Feb 05, 2016 at 09:09:39PM +0100, Michael Lange wrote: > Hi, > > On Fri, 5 Feb 2016 21:44:04 +0200 > Reinis Danne <rei4...@gmail.com> wrote: > > > Hi! > > > > I'm trying to debug why BKChem prints '0' and exits with exit > > code 1. As far as I can tell that is not directly in the app. > > I tried to debug it with gdb, but it tried (and failed) to start > > the app again after I have pressed the close button, so I didn't > > get any useful info out of it. How could I debug this issue? > > just a guess from a quick glance in bkchem.py: > in the if __name__ == '__main__' part of your code you have something > like this: > > myapp.geometry(geometry) > myapp.update_idletasks() > myapp.deiconify() > myapp.mainloop() > myapp.destroy() > > In the following minimal example: > > from Tkinter import * > root = Tk() > root.mainloop() > root.destroy() > > when you click the "X" button in the window corner to close the window, > you will get an exit code 1 along with an error message like this: > > Traceback (most recent call last): > File "test.py", line 6, in <module> > root.destroy() > File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1858, in destroy > self.tk.call('destroy', self._w) > _tkinter.TclError: can't invoke "destroy" command: application has been > destroyed > > Maybe something like this is happening? > > If yes, the solution is to add a handler for the responsible window > manager protocol, as in: > > from Tkinter import * > root = Tk() > root.wm_protocol('WM_DELETE_WINDOW', root.quit) > root.mainloop() > root.destroy() > > > Best regards > > Michael
Thanks for the help! Adding root.wm_protocol('WM_DELETE_WINDOW', root.quit) worked indeed, but only for the close button. It didn't work if I closed the window with Alt+F4 or File->Exit. On further inspection it already used WM_DELETE_WINDOW protocol in main.py::BKChem.initialize() like this: self.protocol("WM_DELETE_WINDOW", self._quit) And then called self.quit() and sys.exit(): def _quit(self): # Do some clean-up self.quit() if os.name != "nt": sys.exit(0) The issue seems to be with the sys.exit() call, removing that fixes the issue. It was introduced in commit ca8deafe48de3f358c09e9a7b9532fa56caff6b4 and was supposed to deal with exiting when editPool widget has been active. Without it the window is not closed if editPool widget has been active (press the button with simbol "N" and click on the paper to activate editPool widget and Enter to deactivate it). Another issue is the self.quit() call. According to the documentation [1] the WM_DELETE_WINDOW protocol handler should call self.destroy(). If I move the bkchem.py::myapp.destroy() to main.py::BKChem._quit() in place of self.quit() call everything still works. So what is the difference between destroy() and quit() and which is better here? From documentation [2]: "The mainloop call enters the Tk event loop, in which the application will stay until the quit method is called (just click the QUIT button), or the window is closed. The destroy call is only required if you run this example under certain development environments; it explicitly destroys the main window when the event loop is terminated. Some development environments won’t terminate the Python process unless this is done." So is either way (with or without the quit() call) ok? It turns out that using destroy() in place of quit() allows to close the app properly even in the case when editPool has been active so there is no need for sys.exit() call. The remaining question is if I'm supposed to do some extra clean-up when deactivating editPool (beyond calling edit_pool.py::editPool._cancel() on it if it is still active; that calls editPool.quit() among other things)? How? Calling destroy() at exit time feels like dealing with the issue with brute force instead of properly cleaning up when deactivating the widget. Reinis [1] http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm#protocols [2] http://effbot.org/tkinterbook/tkinter-hello-again.htm _______________________________________________ Tkinter-discuss mailing list Tkinter-discuss@python.org https://mail.python.org/mailman/listinfo/tkinter-discuss