在我的Tkinter Python应用程序中,我尝试使用sys.excepthook
来处理未捕获的异常,但我的处理程序从未被调用过。堆栈跟踪仍然打印出来。
如何在Tkinter应用程序中处理未捕获的异常?
这是一个显示我尝试过的简单例子:
import Tkinter as tk
import tkMessageBox
import traceback
import sys
class MyApp(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.parent = parent
self.button_frame = tk.Frame(self)
self.button_frame.pack(side='top')
self.button_run = tk.Button(
self.button_frame, text="Run", command=self.run
)
self.button_run.grid(row=0, column=1, sticky='W')
def run(self):
tkMessageBox.showinfo('Info', 'The process is running.')
raise RuntimeError('Tripped.')
def main():
root = tk.Tk() # parent widget
MyApp(root).pack(fill='both', expand=True)
def handle_exception(exc_type, exc_value, exc_traceback):
message = ''.join(traceback.format_exception(exc_type,
exc_value,
exc_traceback))
tkMessageBox.showerror('Error', message)
sys.excepthook = handle_exception
root.mainloop() # enter Tk event loop
if __name__ == '__main__':
main()
答案 0 :(得分:6)
在引发异常后我逐步完成了代码,发现它被report_callback_exception()
捕获。更多搜索引导我发布了一篇文章,展示了如何override report_callback_exception()
。这是我的新处理程序示例。别忘了__init__()
中你实际注册处理程序的第二行。
import Tkinter as tk
import tkMessageBox
import traceback
class MyApp(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
parent.report_callback_exception = self.report_callback_exception
self.parent = parent
self.button_frame = tk.Frame(self)
self.button_frame.pack(side='top')
self.button_run = tk.Button(
self.button_frame, text="Run", command=self.run
)
self.button_run.grid(row=0, column=1, sticky='W')
def run(self):
tkMessageBox.showinfo('Info', 'The process is running.')
raise RuntimeError('Tripped.')
def report_callback_exception(self, exc_type, exc_value, exc_traceback):
message = ''.join(traceback.format_exception(exc_type,
exc_value,
exc_traceback))
tkMessageBox.showerror('Error', message)
def main():
root = tk.Tk() # parent widget
MyApp(root).pack(fill='both', expand=True)
root.mainloop() # enter Tk event loop
if __name__ == '__main__':
main()