Python 我怎样才能在tkinter中使沉默的异常更响亮?
如果从终端运行以下代码,则会在终端中收到一条有用的错误消息:Python 我怎样才能在tkinter中使沉默的异常更响亮?,python,exception,user-interface,tkinter,warnings,Python,Exception,User Interface,Tkinter,Warnings,如果从终端运行以下代码,则会在终端中收到一条有用的错误消息: 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() 但是,如果我在没有终端的情况下运行它(比如双击图
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应用程序中是否有标准的方法公开回溯、标准错误或其他内容?我要找的东西比在任何地方都放try/除外更优雅
编辑:JochenRitzel在下面给出了一个很好的答案,弹出了一个警告框,并提到将其附加到类中。我想明确一点:
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提到了在不同的框架中有不同的异常报告功能的可能性。我还不知道该怎么做。这是显而易见的吗?有
报告\u回调\u异常
可以做到这一点:
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作为tk”导入,请执行以下操作
Tkinter.Tk.report_callback_exception = show_error
首先是后续:就在今天,针对
tkinter.Tk.report\u callback\u异常
docstring的补丁清楚地表明了这一点。当在Windows上的pythonw下运行时,该补丁还(主要)阻止了tk在回调异常时崩溃
第二:这是一个解决方案的简单开头,该解决方案使stderr
功能不带控制台(这应该是一个单独的问题)
需要更多的东西来隐藏弹出窗口,直到需要时,然后使其可见 我在寻找解决相同问题的方法时发现了这个线程。我不得不根据当前的
tkinter
版本方法进行一些修改。我还添加了一个定制的错误消息处理程序,因为我认为我的用户不知道Tk错误消息的含义
在类的\uuuuu init\uuuuu
中包括:
parent.report\u callback\u exception=self.report\u callback\u exception
然后在你的Tk课上:
def report_callback_exception(self, exc, val, tb):
#Handles tkinter exceptions
err_msg = {'Index 0 out of range': 'None found'}
try:
err = err_msg[str(val)]
except KeyError:
err = 'Oops, try again'
messagebox.showerror('Error Found', err)
您可以扩展
err\u msg
字典以包含您想要的任何其他内容。在我的例子中,我正在根据条目
对象构建一个可搜索的数据库,因此,如果用户键入了数据库中不存在的字符串,则会给用户一个简单的语言错误。当您双击图标时,仍然会输出异常。只是你没有在任何地方打印标准。同意!我正在寻找人们推荐一种优雅/标准的方式来向用户公开stdout或stderror。类App
是一个框架,通常派生自tk.frame
。如果您的程序有两个不同的框架类用于不同的事情,那么每个框架类都可以有自己版本的report\u callback\u exception()
,以不同的方式显示错误。在python 3中,tkMessageBox
已移动到tkinter.messagebox
,因此,导入tkinter.messagebox
然后在报告的主体中调用tkinter.messagebox.bathror(…)
。非常好,谢谢!您是否介意详细介绍一下您关于将其放在App类上的评论?@Andrew:我的意思是,通常您将在覆盖此方法的子类中编写应用程序,而不是更改Tk类本身。以防您希望在不同的帧中使用不同的报告函数。相关:如果您有一个用于Tk
的应用程序类,您可以使用def report\u callback\u异常(self、exc、val、tb)覆盖错误处理函数:tkMessageBox.bathror(“exception”,message=str(val))
也适用于python3,但是您需要使用tkinter
模块中的messagebox
,而不是tkMessageBox
。
def report_callback_exception(self, exc, val, tb):
#Handles tkinter exceptions
err_msg = {'Index 0 out of range': 'None found'}
try:
err = err_msg[str(val)]
except KeyError:
err = 'Oops, try again'
messagebox.showerror('Error Found', err)