将标准输出重定向到 tkinter 文本小部件 [英] redirect stdout to tkinter text widget

查看:33
本文介绍了将标准输出重定向到 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

这篇关于将标准输出重定向到 tkinter 文本小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆