将标准输出重定向到 tkinter 文本小部件
我正在尝试将函数的标准输出重定向到 tkinter 文本小部件.我遇到的问题是它将每一行都写入一个新窗口,而不是将所有内容都列在一个窗口中.该函数扫描目录并列出所有为 0k 的文件.如果没有文件是 0k,它会打印出来.所以,问题是如果一个目录中有 30 个 0k 文件,它将打开 30 个窗口,每个窗口只有一行.现在,我知道问题出在哪里了.如果你查看我的函数代码 Zerok()
我告诉它:
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 everything in one.
The function scans a directory and lists any file that is 0k. If no files are 0k it prints that. So, the problem is that if there are 30 0k files in a directory, it will open 30 windows with a single line in each.
Now, I know what the problem is. If you look in my function code Zerok()
I am telling it:
if os.stat(filename).st_size==0:
redirector(filename)
我知道每次 os.stat 看到一个 0k 的文件时,它都会将其发送到重定向器,这就是为什么它为每个文件创建一个新窗口.我只是不知道如何解决它.完整代码如下.感谢您的帮助.
I know that every time os.stat sees a file that is 0k it is then sending that to redirector, that's why its a new window for each file. I just have no idea how to fix it. Complete code below. Thanks for the help.
import Tkinter
from Tkinter import *
import tkFileDialog
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)
def redirector(inputStr):
import sys
root = Tk()
sys.stdout = StdoutRedirector(root)
T = Text(root)
T.pack()
T.insert(END, inputStr)
####This Function checks a User defined directory for 0k files
def Zerok():
import os
sys.stdout.write = redirector #whenever sys.stdout.write is called, redirector is called.
PATH = tkFileDialog.askdirectory(initialdir="/",title='Please select a directory')
for root,dirs,files in os.walk(PATH):
for name in files:
filename=os.path.join(root,name)
if os.stat(filename).st_size==0:
redirector(filename)
else:
redirector("There are no empty files in that Directory")
break
#############################Main GUI Window###########################
win = Tk()
f = Frame(win)
b1 = Button(f,text="List Size")
b2 = Button(f,text="ZeroK")
b3 = Button(f,text="Rename")
b4 = Button(f,text="ListGen")
b5 = Button(f,text="ListDir")
b1.pack()
b2.pack()
b3.pack()
b4.pack()
b5.pack()
l = Label(win, text="Select an Option")
l.pack()
f.pack()
b2.configure(command=Zerok)
win.mainloop()
解决方法很简单:不要创建多个重定向器.重定向器的全部意义在于您创建它一次,然后正常的打印语句将显示在该窗口中.
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.
您需要对 redirector
功能进行一些小的更改.首先,它不应该调用 Tk
;相反,它应该创建一个 Toplevel
的实例,因为 tkinter 程序必须正好有一个根窗口.其次,您必须将文本小部件传递给 IORedirector
,因为它需要知道要写入的确切小部件.
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)
接下来,您应该只调用一次该函数.从那时起,要在窗口中显示数据,您将使用普通的 print
语句.
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()
接下来,您需要修改write
函数,因为它必须写入文本小部件:
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)
最后,更改您的 Zerok
函数以使用打印语句:
Finally, change your Zerok
function to use print statements:
定义 Zerok():...如果 os.stat(filename).st_size==0:
打印(文件名)别的:print("该目录下没有空文件")休息
def Zerok():
...
if os.stat(filename).st_size==0:
print(filename)
else:
print("There are no empty files in that Directory")
break