import sys, traceback
import Tkinter as tk
from ScrolledText import ScrolledText

def do_tb(fd=sys.stderr, args=()):
   fd.write('-- error trap --\n')
   if not args:
      traceback.print_exc(file=fd)
   else:
      traceback.print_exception(*args, **{'file':fd})
   fd.write('--- end trap ---\n')


class Redir:
   def __init__(self, tb):
      self.tb = tb

   def write(self, s):
      tb = self.tb

      tb['state'] =   'normal'
      tb.insert( 'end', s)
      tb['state'] = 'disabled'


class OutBox(tk.Toplevel):
   def __init__(self, tit, cb):
      tk.Toplevel.__init__(self)
      self.title(tit)

      self.tb = \
      tb = ScrolledText(self, state='disabled')
      tb.grid(row=0, column=0, sticky='nsew')

      btn = tk.Button(self, text='Hit Me', command=cb)
      btn.grid(row=1, column=0)


def callback_one():
   print 'Some text to standard output'

def callback_two():
   raise BogusError

def callback_three():
   try:
      int('yee dorks')
   except ValueError:
      do_tb(tbfd)

top = tk.Tk()
top.title('Redirection in Tkinter')

btn = tk.Button(top, text='Push me to quit', command=top.quit)
btn.grid()

ob1 = OutBox('standard output', callback_one)
rd1 = Redir(ob1.tb)
sys.stdout = rd1

ob2 = OutBox('standard error', callback_two)
rd2 = Redir(ob2.tb)
sys.stderr = rd2

ob3 = OutBox('trapped exceptions', callback_three)
rd3 = Redir(ob3.tb)
tbfd = rd3

top.mainloop()