Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Saving exceptions in Tkinter using Python

Tags:

python

tkinter

I have developed several Python programs for others that use Tkinter to receive input from the user. In order to keep things simple and user-friendly, the command line or python console are never brought up (ie. .pyw files are used), so I'm looking into using the logging library to write error text to a file when an exception occurs. However, I'm having difficulty getting it to actually catch the exceptions. For example:

We write a function that will cause an error:

def cause_an_error():
    a = 3/0

Now we try to log the error normally:

import logging
logging.basicConfig(filename='errors.log', level=logging.ERROR)

try:
    cause_an_error()
except:
    logging.exception('simple-exception')

As expected, the program errors, and logging writes the error to errors.log. Nothing appears in the console. However, there is a different result when we implement a Tkinter interface, like so:

import logging
import Tkinter
logging.basicConfig(filename='errors.log', level=logging.ERROR)

try:
    root = Tkinter.Tk()
    Tkinter.Button(root, text='Test', command=cause_an_error).pack()
    root.mainloop()
except:
    logging.exception('simple-exception')

In this case, pressing the button in the Tkinter window causes the error. However, this time, nothing is written to the file, and the following error appears in the console:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1536, in __call__
    return self.func(*args)
  File "C:/Users/samk/Documents/GitHub/sandbox/sandbox2.pyw", line 8, in cause_an_error
    a = 3/0
ZeroDivisionError: integer division or modulo by zero

Is there a different way to catch and log this error?

like image 492
Sam Krygsheld Avatar asked Sep 09 '26 14:09

Sam Krygsheld


1 Answers

It's not very well documented, but tkinter calls a method for exceptions that happen as the result of a callback. You can write your own method to do whatever you want by setting the attribute report_callback_exception on the root window.

For example:

import tkinter as tk

def handle_exception(exception, value, traceback):
    print("Caught exception:", exception)

def raise_error():
    raise Exception("Sad trombone!")

root = tk.Tk()
# setup custom exception handling
root.report_callback_exception=handle_exception

# create button that causes exception
b = tk.Button(root, text="Generate Exception", command=raise_error)
b.pack(padx=20, pady=20)

root.mainloop()

For reference:

  • http://epydoc.sourceforge.net/stdlib/Tkinter.Tk-class.html#report_callback_exception
like image 165
Bryan Oakley Avatar answered Sep 11 '26 05:09

Bryan Oakley



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!