I\'m trying to redirect the stdout of a function to a tkinter text widget. The problem I am running into is that it writes each line to a new window instead of listing every
The above solution is very complete; I was able to essentially copy and paste it into my code with only one small modification. I'm not entirely sure why, but the StdoutRedirector
requires a flush method.
I'm guessing it's because sys.stdout
calls a flush()
method when it exits, but I'm haven't waded into the docs deep enough to actually understand what that means.
Running the above code in the Jupyter environment caused the code to hang indefinitely until the kernel was restarted. The console kicks the following errors:
sys.stdout.flush()
AttributeError: 'StdoutRedirector' object has no attribute 'flush'
ERROR:tornado.general:Uncaught exception, closing connection.
The simple solution is to make a small change to the StdoutRedirector
class by adding a flush method.
class StdoutRedirector(IORedirector):
'''A class for redirecting stdout to this Text widget.'''
def write(self,str):
self.text_area.insert("end", str)
def flush(self):
pass
Thanks to the giants that came before me and offered this very clear explanation.
The fix is simple: don't create more than one redirector. The whole point of the redirector is that you create it once, and then normal print statements will show up in that window.
You'll need to make a couple of small changes to your redirector
function. First, it shouldn't call Tk
; instead, it should create an instance of Toplevel
since a tkinter program must have exactly one root window. Second, you must pass a text widget to IORedirector
since it needs to know the exact widget to write to.
def redirector(inputStr=""):
import sys
root = Toplevel()
T = Text(root)
sys.stdout = StdoutRedirector(T)
T.pack()
T.insert(END, inputStr)
Next, you should only call this function a single time. From then on, to have data appear in the window you would use a normal print
statement.
You can create it in the main block of code:
win = Tk()
...
r = redirector()
win.mainloop()
Next, you need to modify the write
function, since it must write to the text widget:
class StdoutRedirector(IORedirector):
'''A class for redirecting stdout to this Text widget.'''
def write(self,str):
self.text_area.insert("end", str)
Finally, change your Zerok
function to use print statements:
def Zerok():
...
if os.stat(filename).st_size==0:
print(filename)
else:
print("There are no empty files in that Directory")
break