Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 我怎样才能在tkinter中使沉默的异常更响亮?_Python_Exception_User Interface_Tkinter_Warnings - Fatal编程技术网

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)