Spad
Spad

Reputation: 41

Clear/ delete redirected text in tkinter text widget

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

Upvotes: 1

Views: 792

Answers (1)

stovfl
stovfl

Reputation: 15513

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()

Upvotes: 1

Related Questions