使用Tkinter处理未捕获的异常

Don*_*kby 0 python tkinter

在我的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()
Run Code Online (Sandbox Code Playgroud)

Don*_*kby 7

在引发异常后我逐步完成了代码,发现它被捕获了report_callback_exception().一些更多的搜索引导我到一个显示如何覆盖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()
Run Code Online (Sandbox Code Playgroud)