【问题标题】:tkinter python: catching exceptionstkinter python:捕获异常
【发布时间】:2011-07-12 15:35:24
【问题描述】:

开始使用 python 编程,我对它的错误报告感到宾至如归。现在我正在使用 Tkinter 进行编程,我发现我的程序中经常出现错误,即使它们产生异常我也不会注意到:我捕获它们(有时)只是因为我去调试步骤(我使用wingIDE)和例如在给定的行上,我看到报告的异常。但让我恼火的是程序并没有停止,甚至在 try/error 中的块 not 中也会发生这种情况。

如果我说的有道理,你知道一些至少显示错误的整体方法吗?在 Tkinter 中,我可以创建一个错误窗口,并在发生异常时填充它。

【问题讨论】:

标签: python error-handling tkinter


【解决方案1】:

正如@jochen-ritzel 所说 (Should I make silent exceptions louder in tkinter?),您可以覆盖 tk.TK.report_callback_exception()

import traceback
import tkMessageBox

# You would normally put that on the App class
def show_error(self, *args):
    err = traceback.format_exception(*args)
    tkMessageBox.showerror('Exception',err)
# but this works too
tk.Tk.report_callback_exception = show_error

【讨论】:

    【解决方案2】:

    我更喜欢显式扩展 Tk 的 Toplevel 小部件,它主要代表应用程序的主窗口,而不是注入 hack:

    import tkinter as tk
    from tkinter import messagebox
    
    class FaultTolerantTk(tk.Tk):
        def report_callback_exception(self, exc, val, tb):
            self.destroy_unmapped_children(self)
            messagebox.showerror('Error!', val)
    
        # NOTE: It's an optional method. Add one if you have multiple windows to open
        def destroy_unmapped_children(self, parent):
            """
            Destroys unmapped windows (empty gray ones which got an error during initialization)
            recursively from bottom (root window) to top (last opened window).
            """
            children = parent.children.copy()
            for index, child in children.items():
                if not child.winfo_ismapped():
                    parent.children.pop(index).destroy()
                else:
                    self.destroy_unmapped_children(child)
    
    def main():
        root = FaultTolerantTk()
        ...
        root.mainloop()
    
    
    if __name__ == '__main__':
        main()
    

    恕我直言,这看起来是正确的方法。

    【讨论】:

      【解决方案3】:

      查看How can I make silent exceptions louder in tkinter 的答案,其中展示了如何将回调挂钩到tkinter.Tk.report_callback_exception

      【讨论】:

      • 感谢您的帮助,我可以或多或少让它工作。但我不熟悉@safe 语法(新手 python 程序员),所以我不知道将它放在我的代码中的确切位置......在我看来,我必须将 @safe 放在每个应该的函数定义之前被监视……是这样吗?
      • @alessandro:你是对的。这些被称为装饰器。装饰器是调用可以包装其他函数的类和函数的语法糖。
      • @StevenRumbalski 我故意让导入保持不变。我只进行了向后兼容 Python 2 的编辑。
      • @StevenRumbalski 我认为 print 是向前兼容的,无需导入未来?
      • @StevenVascellaro:如果没有未来的导入,print 3print(3) 是相同的,但 print 1, 2, 3print(1, 2, 3) 的输出分别为 1 2 3(1, 2, 3)。并且做print(1, end='') 是一个语法错误。单个参数没有问题,因为括号可以忽略。多个参数成为一个元组,因为逗号。我认为命名参数是一个问题,因为 Python 已经确定 print 是一个语句,因此它甚至没有试图将其视为一个函数。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 1970-01-01
      • 2011-06-09
      • 2017-12-30
      • 2012-11-11
      • 1970-01-01
      • 2017-04-27
      相关资源
      最近更新 更多