我有一个Python脚本,如果发生意外异常,它会使用tkinter.messagebox
显示带有回溯详细信息的错误消息。
import tkinter.messagebox as tm
import traceback
try:
1/0
except Exception as error:
tm.showerror(title="Error",
message="An error has occurred: '" + str(error) + "'.",
detail=traceback.format_exc())
以这种方式显示回溯有一些缺点。
我希望添加一个"显示详细信息"而不是默认显示错误详细信息。按钮,它将在只读文本字段中显示更多信息。
如何添加"显示详细信息"按钮到tkinter消息框?
答案 0 :(得分:7)
我会使用Toplevel()
窗口来构建我自己的客户错误框。
我认为在这里使用ttk
按钮会是一个好主意,并且通过框架和权重的组合,我们可以让窗口显得足够好。
保持窗口不被用户调整大小我还必须设置一种切换详细信息文本框的方法。使用跟踪变量并使用易于设置的if / else语句。
最后,我们可以使用.config(state="disabled")
import tkinter as tk
import tkinter.ttk as ttk
import traceback
class MyApp(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
tk.Button(self, text="test error", command=self.run_bad_math).pack()
def run_bad_math(self):
try:
1/0
except Exception as error:
title = "Traceback Error"
message = "An error has occurred: '{}'.".format(error)
detail = traceback.format_exc()
topErrorWindow(title, message, detail)
class topErrorWindow(tk.Toplevel):
def __init__(self, title, message, detail):
tk.Toplevel.__init__(self)
self.details_expanded = False
self.title(title)
self.geometry("350x75")
self.minsize(350, 75)
self.maxsize(425, 250)
self.rowconfigure(0, weight=0)
self.rowconfigure(1, weight=1)
self.columnconfigure(0, weight=1)
button_frame = tk.Frame(self)
button_frame.grid(row=0, column=0, sticky="nsew")
button_frame.columnconfigure(0, weight=1)
button_frame.columnconfigure(1, weight=1)
text_frame = tk.Frame(self)
text_frame.grid(row=1, column=0, padx=(7, 7), pady=(7, 7) ,sticky="nsew")
text_frame.rowconfigure(0, weight=1)
text_frame.columnconfigure(0, weight=1)
ttk.Label(button_frame, text=message).grid(row=0, column=0, columnspan=2, pady=(7, 7))
ttk.Button(button_frame, text="OK", command=self.destroy).grid(row=1, column=0, sticky="e")
ttk.Button(button_frame, text="Details", command=self.toggle_details).grid(row=1, column=1, sticky="w")
self.textbox = tk.Text(text_frame, height=6)
self.textbox.insert("1.0", detail)
self.textbox.config(state="disabled")
self.scrollb = tk.Scrollbar(text_frame, command=self.textbox.yview)
self.textbox.config(yscrollcommand=self.scrollb.set)
def toggle_details(self):
if self.details_expanded == False:
self.textbox.grid(row=0, column=0, sticky='nsew')
self.scrollb.grid(row=0, column=1, sticky='nsew')
self.geometry("350x160")
self.details_expanded = True
else:
self.textbox.grid_forget()
self.scrollb.grid_forget()
self.geometry("350x75")
self.details_expanded = False
if __name__ == "__main__":
root = tk.Tk()
App = MyApp(root).pack()
root.mainloop()
结果:
现在调整大小:D
更新
回应你的陈述:
如果尚未首先初始化Tk实例,则不会显示错误窗口。
如果我们将类设置为自己的Tk()
实例,则可以将其用作独立错误弹出窗口。我还添加了一些对齐更改和一些调整大小控制,以使此类更符合您在注释中提到的标准错误消息。
见下面的代码。
import tkinter as tk
import tkinter.ttk as ttk
import traceback
class topErrorWindow(tk.Tk):
def __init__(self, title, message, detail):
tk.Tk.__init__(self)
self.details_expanded = False
self.title(title)
self.geometry("350x75")
self.minsize(350, 75)
self.maxsize(425, 250)
self.resizable(False, False)
self.rowconfigure(0, weight=0)
self.rowconfigure(1, weight=1)
self.columnconfigure(0, weight=1)
button_frame = tk.Frame(self)
button_frame.grid(row=0, column=0, sticky="nsew")
button_frame.columnconfigure(0, weight=1)
button_frame.columnconfigure(1, weight=1)
text_frame = tk.Frame(self)
text_frame.grid(row=1, column=0, padx=(7, 7), pady=(7, 7) ,sticky="nsew")
text_frame.rowconfigure(0, weight=1)
text_frame.columnconfigure(0, weight=1)
ttk.Label(button_frame, text=message).grid(row=0, column=0, columnspan=3, pady=(7, 7), padx=(7, 7), sticky="w")
ttk.Button(button_frame, text="OK", command=self.destroy).grid(row=1, column=1, sticky="e")
ttk.Button(button_frame, text="Details", command=self.toggle_details).grid(row=1, column=2, padx=(7, 7), sticky="e")
self.textbox = tk.Text(text_frame, height=6)
self.textbox.insert("1.0", detail)
self.textbox.config(state="disabled")
self.scrollb = tk.Scrollbar(text_frame, command=self.textbox.yview)
self.textbox.config(yscrollcommand=self.scrollb.set)
self.mainloop()
def toggle_details(self):
if self.details_expanded == False:
self.textbox.grid(row=0, column=0, sticky='nsew')
self.scrollb.grid(row=0, column=1, sticky='nsew')
self.resizable(True, True)
self.geometry("350x160")
self.details_expanded = True
else:
self.textbox.grid_forget()
self.scrollb.grid_forget()
self.resizable(False, False)
self.geometry("350x75")
self.details_expanded = False
结果:
您也可以使用带有所需错误图像类型的画布添加图像。