I have written an application in Python Tkinter. I recently noticed that for one of the operation, it sometimes closes (without giving any error) if that operation failed.
I see you have a non-object oriented example, so I'll show two variants to solve the problem of exception-catching.
The key is in the in the tkinter\__init__.py file. One can see that there is a documented method report_callback_exception of Tk class. Here is its description:
report_callback_exception()Report callback exception on sys.stderr.
Applications may want to override this internal function, and should when sys.stderr is None.
So as we see it it is supposed to override this method, lets do it!
Non-object oriented solution
import tkinter as tk
from tkinter.messagebox import showerror
if __name__ == '__main__':
def bad():
raise Exception("I'm Bad!")
# any name as accepted but not signature
def report_callback_exception(self, exc, val, tb):
showerror("Error", message=str(val))
tk.Tk.report_callback_exception = report_callback_exception
# now method is overridden
app = tk.Tk()
tk.Button(master=app, text="bad", command=bad).pack()
app.mainloop()
Object oriented solution
import tkinter as tk
from tkinter.messagebox import showerror
class Bad(tk.Tk):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# or tk.Tk.__init__(*args, **kwargs)
def bad():
raise Exception("I'm Bad!")
tk.Button(self, text="bad", command=bad).pack()
def report_callback_exception(self, exc, val, tb):
showerror("Error", message=str(val))
if __name__ == '__main__':
app = Bad()
app.mainloop()
The result
My environment:
Python 3.5.1 |Anaconda 2.4.1 (64-bit)| (default, Dec 7 2015, 15:00:12) [MSC
v.1900 64 bit (AMD64)] on win32
tkinter.TkVersion
8.6
tkinter.TclVersion
8.6