Question Details

No question body available.

Tags

python tkinter stdout

Answers (1)

April 29, 2026 Score: 4 Rep: 150,175 Quality: Medium Completeness: 60%

Your main() runs before you run OutputRedirectorGUI() so it runs before you create redirection - so it can't redirect to tk.

You would have to create OutputRedirectorGUI() before main(). But it also needs to start mainloop() and this makes problem to run main() and mainloop() at the same time.

You may have to use threading to run main() at the same time (after creating redirection).

And it may need to use root.after() to start a thread with main() shortly after starting mainloop() (because widgets will not update content with redirected text if main() will start displaying text before mainloop() will work)

def startotherprocess(functionname):
    p = threading.Thread(target=functionname)
    p.start()

--- main ---

sys.stdout = TextWidgetStream(text) sys.stderr = TextWidgetStream(text)

it will start thread withmain() 100ms after starting mainloop()

root.after(100, startotherprocess, main)

root.mainloop()

Minimal working code:

import io
import tkinter as tk
import threading
import time
import sys

def main(): for i in range(10): print(i) time.sleep(0.5)

---

class TextWidgetStream(io.TextIOBase): def init(self, textwidget, tag="stdout"): super().init() self.textwidget = textwidget self.tag = tag # Tag for coloring

def write(self, s): self.text
widget.after(0, self.inserttext, s)

def inserttext(self, s): self.textwidget.config(state="normal") self.textwidget.insert("end", s, (self.tag,)) self.textwidget.see("end") # Auto-scroll to bottom self.textwidget.config(state="disabled")

def flush(self): pass # Required for stream compliance

def startotherprocess(functionname): # it may need daemon=True to stop thread if window will be closed before end of thread. p = threading.Thread(target=functionname, daemon=True) p.start()

---

originalstdout = sys.stdout originalstderr = sys.stderr

root = tk.Tk()

button = tk.Button(root, text="Close", command=root.destroy) button.pack()

text = tk.Text(root) text.pack()

sys.stdout = TextWidgetStream(text) sys.stderr = TextWidgetStream(text)

it will start thread withmain() 100ms after starting mainloop()

root.after(100, startotherprocess, main)

root.mainloop()

sys.stdout = originalstdout sys.stderr = originalstderr