1

as the title says, I have a text widget where I redirect print() to. To do so I use

class TextRedirector(object):
    def write(self, str):
        main_text.insert(1.0, str)

and then

sys.stdout = TextRedirector()

What I cannot do is to clear the text before I insert the new one. To do this I add main_text.delete(1.0, "end") as it follows

class TextRedirector(object):
    def write(self, str):
        main_text.delete(1.0, "end")
        main_text.insert(1.0, str)

This results in nothing printed at all.

I also tried to just print a text in the widget like so

text = "my test is here"
class TextRedirector(object):
    def write(self, str):
        main_text.delete(1.0, "end")
        main_text.insert(1.0, text)

And it works just fine. It clears whatever I type in (as I keep it state="normal") and prints my text.

Any help will be much appreciated!

EDIT:

Here is the code from this post that you can use as an example.

import tkinter as tk
import sys

class ExampleApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        toolbar = tk.Frame(self)
        toolbar.pack(side="top", fill="x")
        b1 = tk.Button(self, text="print to stdout", command=self.print_stdout)
        b1.pack(in_=toolbar, side="left")
        self.text = tk.Text(self, wrap="word")
        self.text.pack(side="top", fill="both", expand=True)
        sys.stdout = TextRedirector(self.text)

    def print_stdout(self):
        print("This is my text")

class TextRedirector(object):
    def __init__(self, widget, tag="data"):
        self.widget = widget
        self.tag = tag

    def write(self, str):
        self.widget.configure(state="normal")
        #self.widget.delete(1.0, "end")
        self.widget.insert("end", str, (self.tag,))

app = ExampleApp()
app.mainloop()

Same as in my code, if you remove the # from def write(self, str) function, it will not print the text.

What I want is to redirect print() to the text widget but every time to be in a clear textbox and not as a new line. That means, If i press the b1 button from the above code 4 times I will have this in the textbox

This is my text

and not this

This is my text
This is my text
This is my text
This is my text
Spad
  • 41
  • 4
  • I wouldn't mind trying to help. But it's rather unclear to me what you intend to do. Do you have some more code that I can test run? – PythonAmateur742 May 13 '20 at 17:37
  • 1
    `print()` can result in an arbitrarily large number of calls to the `.write()` method of your redirected output. I'm pretty sure it *did* actually display the text you printed - but that was overwritten immediately by the separate `.write()` of a newline character. You're going to need to keep the text around for longer, perhaps keep the last N lines of text. – jasonharper May 13 '20 at 18:28
  • Thank you guys! I added the source of my example and I tries to make more clear what I am trying to do. – Spad May 13 '20 at 19:31
  • Try ignoring `str` when `str == '\n'`. – acw1668 May 14 '20 at 01:49

1 Answers1

1

Use the default end=\n wich print ist using to set a flag when to delete. Live-Demo: reply.it


import tkinter as tk
import sys, threading

class ExampleApp(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        toolbar = tk.Frame(self)
        toolbar.pack(side="top", fill="x")
        b1 = tk.Button(self, text="print to stdout", height=5, command=self.print_stdout)
        b1.pack(in_=toolbar, side="left")
        self.text = tk.Text(self, wrap="word")
        self.text.pack(side="top", fill="both", expand=True)

        self._count = 1
        self._stdout = sys.stdout
        sys.stdout = TextRedirector(self.text)

    def print_stdout(self):
        print("This my text {}".format(self._count))
        self._count += 1

class TextRedirector(object):
    def __init__(self, widget, tag="data"):
        self.widget = widget
        self.tag = tag
        self.eof = False

    def write(self, str):
        if self.eof:
            self.eof = False
            self.widget.delete(1.0, "end")

        if str == "\n":
            str += " thread_ident: {}".format(threading.get_ident())
            self.eof = True

        self.widget.insert("end", str, (self.tag,))


app = ExampleApp()
app.mainloop()

stovfl
  • 14,998
  • 7
  • 24
  • 51