Source code for labscript_utils.excepthook.tk_exception

#####################################################################
#                                                                   #
# tk_exception.py                                                   #
#                                                                   #
# Copyright 2013, Monash University                                 #
#                                                                   #
# This file is part of the labscript suite (see                     #
# http://labscriptsuite.org) and is licensed under the Simplified   #
# BSD License. See the license.txt file in the root of the project  #
# for the full license.                                             #
#                                                                   #
#####################################################################

import sys
import os

import tkinter
import tkinter.constants as constants

error_im_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'error.gif')


[docs] class ErrorWindow(tkinter.Text): """Class to display the error in a textbox. Parts copied from Tkinter's ScrolledText widget"""
[docs] def __init__(self, master=None, **kw): self.frame = tkinter.Frame(master, padx=10, pady=10) self.upperframe = tkinter.Frame(self.frame) self.upperframe.pack(side=constants.TOP, fill=constants.X) self.lowerframe = tkinter.Frame(self.frame, pady=10) self.lowerframe.pack(side=constants.TOP, fill=constants.BOTH, expand=True) self.imlabel = tkinter.Label(self.upperframe, borderwidth=10, image=error_im) self.imlabel.pack(side=constants.LEFT) self.textlabel = tkinter.Label(self.upperframe, text='It looks like an error has occured:\n%s' % sys.argv[2], borderwidth=10, wraplength=400, justify='left') self.textlabel.pack(side=constants.LEFT) self.vbar = tkinter.Scrollbar(self.lowerframe) self.vbar.pack(side=constants.RIGHT, fill=constants.Y) self.button = tkinter.Button(self.frame, text='Ok', command=self.ok_clicked, padx=20, pady=5) self.button.bind('<Return>', self.ok_clicked) self.button.pack(side=constants.BOTTOM) kw.update({'yscrollcommand': self.vbar.set}) tkinter.Text.__init__(self, self.lowerframe, **kw) self.pack(side=constants.LEFT, fill=constants.BOTH, expand=True) self.vbar['command'] = self.yview # Copy geometry methods of self.frame without overriding Text # methods -- hack! text_meths = list(vars(tkinter.Text).keys()) methods = list(vars(tkinter.Pack).keys()) + list(vars(tkinter.Grid).keys()) + list(vars(tkinter.Place).keys()) methods = set(methods).difference(text_meths) for m in methods: if m[0] != '_' and m != 'config' and m != 'configure': setattr(self, m, getattr(self.frame, m)) self.button.bind('<<Copy>>', self.copy)
[docs] def ok_clicked(self, *ignore): win.quit()
[docs] def copy(self, event=None): self.clipboard_clear() text = self.get("sel.first", "sel.last") self.clipboard_append(text)
if __name__ == "__main__": win = tkinter.Tk() error_im = tkinter.PhotoImage(file=error_im_path) win.title('Unhandled exception in %s' % sys.argv[1]) win.tk.call('wm', 'iconphoto', win._w, error_im) win.geometry('500x500') stext = ErrorWindow(master=win, bg='black', height=10, fg='red', font=("monospace", 10, "bold")) stext.insert(constants.END, sys.argv[3]) stext.pack(fill=constants.BOTH, side=constants.LEFT, expand=True) stext.config(state=constants.DISABLED) stext.button.focus_set() stext.mainloop()