如果我从终端运行以下代码,我会在终端中收到有用的错误消息:
import Tkinter as tk
master = tk.Tk()
def callback():
raise UserWarning("Exception!")
b = tk.Button(master, text="This will raise an exception", command=callback)
b.pack()
tk.mainloop()
但是,如果我在没有终端的情况下运行它(例如,通过双击图标),则会禁止显示错误消息。
在我真实的,更复杂的Tkinter应用程序中,我喜欢GUI有点防撞击。我不喜欢我的用户很难给我有用的反馈来解决导致的意外行为。
我该怎么处理?是否有一种标准方法可以在Tkinter应用程序中公开回溯或stderr或诸如此类的东西?我正在寻找比尝试/除了各处更优雅的东西。
编辑:Jochen Ritzel给出了一个很好的答案,弹出一个警告框,并提到将它附加到一个班级。只是为了明确这一点:
import Tkinter as tk
import traceback, tkMessageBox
class App:
def __init__(self, master):
master.report_callback_exception = self.report_callback_exception
self.frame = tk.Frame(master)
self.frame.pack()
b = tk.Button(
self.frame, text="This will cause an exception",
command=self.cause_exception)
b.pack()
def cause_exception(self):
a = []
a.a = 0 #A traceback makes this easy to catch and fix
def report_callback_exception(self, *args):
err = traceback.format_exception(*args)
tkMessageBox.showerror('Exception', err)
root = tk.Tk()
app = App(root)
root.mainloop()
我仍然存在困惑:Jochen提到了在不同的框架中具有不同异常报告功能的可能性。我还没看到怎么做。这显而易见吗?
有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
如果你没有导入'Tkinter as tk',那么就做
Tkinter.Tk.report_callback_exception = show_error
首先是后续:就在今天,CPython tracker docstring的tkinter.Tk.report_callback_exception
上的一个补丁明确表示Jochen's solution是有意的。在Windows上的pythonw下运行时,补丁也(并且主要)停止了对回调异常的崩溃。
第二:这是一个简单的开始,解决方案,使stderr
功能没有控制台(这应该是一个单独的SO问题)。
import sys, tkinter
root = tkinter.Tk()
class Stderr(tkinter.Toplevel):
def __init__(self):
self.txt = tkinter.Text(root)
self.txt.pack()
def write(self, s):
self.txt.insert('insert', s)
sys.stderr = Stderr()
1/0 # traceback appears in window
需要更多的东西来保持弹出窗口隐藏直到需要,然后使其可见。