9

How can I redirect stdout data to a tkinter Text widget?

rbrito
  • 2,398
  • 2
  • 21
  • 24
FLX
  • 4,634
  • 14
  • 47
  • 60

3 Answers3

14

You need to make a file-like class whose write method writes to the Tkinter widget instead, and then do sys.stdout = <your new class>. See this question.

Example (copied from the link):

class IORedirector(object):
    '''A general class for redirecting I/O to this Text widget.'''
    def __init__(self,text_area):
        self.text_area = text_area

class StdoutRedirector(IORedirector):
    '''A class for redirecting stdout to this Text widget.'''
    def write(self,str):
        self.text_area.write(str,False)

and then, in your Tkinter widget:

# To start redirecting stdout:
import sys
sys.stdout = StdoutRedirector( self )
# (where self refers to the widget)

# To stop redirecting stdout:
sys.stdout = sys.__stdout__
Community
  • 1
  • 1
Katriel
  • 120,462
  • 19
  • 136
  • 170
  • Hi! Could you maybe provide me with an example? I'm very new with python and I'm struggling to get this to work. Much obliged :) – FLX Jul 26 '10 at 18:35
  • The linked question has all the code you need, I think. You need to make your own version of the class `StdoutRedirector` as is done there, then set `sys.stdout = StdoutRedirector`. I'll copy the code into my answer. – Katriel Jul 27 '10 at 08:32
4

This is an old question, but I found a solution which I would like to share with the community. My example pipes a listing of the working directory to a Tk window. I am using Python 3.6 on Windows 8. I ran the code through both Jupyter Notebook and Eclipse using Pydev.

import os
from tkinter import *
from subprocess import Popen, PIPE
root = Tk()
text = Text(root)
text.pack()

def ls_proc():
    return Popen(['ls'], stdout=PIPE)

with ls_proc() as p:
    if p.stdout:
        for line in p.stdout:
            text.insert(END, line)
    if p.stderr:
        for line in p.stderr:
            text.insert(END, line)

root.mainloop()
Oppy
  • 2,662
  • 16
  • 22
1
log_box_1 = tk.Text(root, borderwidth=3, relief="sunken")

with subprocess.Popen("ls -la", shell=True, stdout=subprocess.PIPE, bufsize=1, universal_newlines=True) as p:
            for line in p.stdout:
                log_box_1.insert(tk.END, line)

From here

Lucas
  • 1,514
  • 3
  • 16
  • 23