widgets descargar python exception user-interface tkinter warnings

python - descargar - ¿Cómo puedo hacer más silenciosas las excepciones en tkinter?



tkinter syntax (2)

Si ejecuto el siguiente código desde un terminal, recibo un mensaje de error útil en el terminal:

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()

Sin embargo, si lo ejecuto sin un terminal (por ejemplo, al hacer doble clic en un icono), el mensaje de error se suprime.

En mi aplicación Tkinter real y más complicada, me gusta que la GUI sea un poco resistente a las fallas. No me gusta que a mis usuarios les resulte difícil ofrecerme comentarios útiles para corregir el comportamiento inesperado resultante.

¿Cómo debería manejar esto? ¿Hay una forma estándar de exponer las trazas o stderror o lo que sea en una aplicación Tkinter? Estoy buscando algo más elegante que poner try / excepto en todas partes.

EDITAR: Jochen Ritzel dio una excelente respuesta a continuación que aparece un cuadro de advertencia, y mencionó que se adjunta a una clase. Solo para hacer esto explícito:

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()

Mi confusión restante: Jochen menciona la posibilidad de tener diferentes funciones de informes de excepción en diferentes marcos. Todavía no veo cómo hacer eso. ¿Es esto obvio?


Hay report_callback_exception para hacer esto:

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

Si no importó ''Tkinter como tk'', entonces haga

Tkinter.Tk.report_callback_exception = show_error


Primero un seguimiento: Hoy mismo, un parche en el rastreador de CPython para la tkinter.Tk.report_callback_exception tkinter.Tk.report_callback_exception dejó en claro que la solución de Jochen es intencional. El parche también (y principalmente) evitó que tk se bloquee en las excepciones de devolución de llamada cuando se ejecuta bajo pythonw en Windows.

Segundo: aquí hay un comienzo escueto de una solución para hacer que la función stderr no tenga consola (esto realmente debería ser una pregunta SO separada).

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

Se necesita más para mantener oculta la ventana emergente hasta que sea necesario y luego hacerla visible.