Если я запускаю следующий код из терминала, я получаю полезное сообщение об ошибке в терминале:
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 мне нравится, что графический интерфейс немного устойчив к сбоям. Мне не нравится, что моим пользователям трудно дать мне полезную обратную связь, чтобы исправить полученное неожиданное поведение.
Как мне справиться с этим? Есть ли стандартный способ выставить трассировку или stderror или еще что-то в приложении Tkinter? Я ищу что-то более элегантное, чем везде ставить try/except.
РЕДАКТИРОВАТЬ: Йохен Ритцель дал отличный ответ ниже, в котором появляется окно с предупреждением, и упомянул о присоединении его к классу. Просто чтобы сделать это явным:
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()
Моя оставшаяся путаница: Йохен упоминает о возможности использования разных функций отчетности об исключениях в разных фреймах. Я пока не вижу, как это сделать. Это очевидно?
App
— это фрейм, обычно производный отtk.Frame
. Если бы в вашей программе было два разных класса фреймов, которые использовались для разных целей, то каждый класс фреймов мог бы иметь свою собственную версиюreport_callback_exception()
, отображающую ошибку по-разному. - person Don Kirkby   schedule 24.08.2015tkMessageBox
переместился вtkinter.messagebox
, поэтомуimport tkinter.messagebox
затем в телеreport_callback
tkinter.messagebox.showerror(...)
. - person PeterK   schedule 13.06.2021