如何将标准输出重定向到 Tkinter Text 小部件

Posted

技术标签:

【中文标题】如何将标准输出重定向到 Tkinter Text 小部件【英文标题】:How to redirect stdout to a Tkinter Text widget 【发布时间】:2013-09-02 05:58:56 【问题描述】:

我的基础程序从脚本 GUI.py 导入它的 GUI 界面

old_stdout = sys.stdout

root = Tk.Tk()
root.title('Coursera-dl')
root.geometry("345x230")
app = GUI.Interface(root)
app.mainloop()

if app.button_press() == True and app.return_data():
    data = app.return_data()
    main(data[0],data[1],data[2],data[3],data[4],data[5],data[6],data[7],data[8])

sys.stdout = old_stdout

在我的 GUI.py 中:

class Interface(ttk.Frame):
    def __init__(self,parent=None):
        ttk.Frame.__init__(self,parent)
        self.parent = parent
        self.New_Window()

    def New_Window(self):
        self.newWindow = Tk.Toplevel(self.parent)
        self.app = CoreGUI(self.newWindow)


class StdoutRedirector(object):
    def __init__(self,text_widget):
        self.text_space = text_widget

    def write(self,string):
        self.text_space.insert('end', string)
        self.text_space.see('end')


class CoreGUI(object):
    def __init__(self,parent):
        self.parent = parent
        self.InitUI()

    def InitUI(self):
        self.text_box = Tk.Text(self.parent, wrap='word', height = 11, width=50)
        self.text_box.grid(column=0, row=0, columnspan = 2, sticky='NSWE', padx=5, pady=5)
        sys.stdout = StdoutRedirector(self.text_box)

但它的作用是打开两个窗口,第一个窗口 (顶层) 按预期工作,第二个是 idle这就是预计直到我点击某个按钮,该按钮在按下后连续打印数据并且打印的数据应该出现在第二个窗口的文本小部件中但是这不会发生,并且没有响应程序,当我关闭顶层窗口时,会出现一条错误消息

"TclError: 无效的命令名称"".33328904.33329104"""

那么如何在 Text Widget 中而不是在控制台中打印数据?


编辑:

如果您遇到此问题,为了帮助您,我制作了一个脚本来将标准输出重定向到 Tkinter Text 小部件,查看它的实际操作here :-)

【问题讨论】:

创建一个short, self-contained, runnable example 来证明您的问题可能对您有所帮助。 SO (as there should be) 上有很多懒惰的用户,所以你越容易调试你的程序,你得到的答案就越多。 链接是404 @Nicoolasens 对不起,该帐户早已被自动删除,无法恢复。您可以在 github 上搜索该名称,似乎其他人复制了我的部分代码,因此您可以像恢复它一样那个。 【参考方案1】:

问题是当你调用app.mainloop()时,线程正忙于执行Tkinter主循环,所以它之前的语句直到你退出循环才会执行。但是一旦你退出主循环,你会尝试使用 Text 小部件,但它已经被销毁了。

我建议您将对main 的调用移动到Tkinter 小部件的回调中(我想您已经尝试使用app.button_press() 执行此操作),因此可以使用Text 对象来显示文本。

class CoreGUI(object):
    def __init__(self,parent):
        self.parent = parent
        self.InitUI()
        button = Button(self.parent, text="Start", command=self.main)
        button.grid(column=0, row=1, columnspan=2)

    def main(self):
        print('whatever')

    def InitUI(self):
        self.text_box = Text(self.parent, wrap='word', height = 11, width=50)
        self.text_box.grid(column=0, row=0, columnspan = 2, sticky='NSWE', padx=5, pady=5)
        sys.stdout = StdoutRedirector(self.text_box)


root = Tk()
gui = CoreGUI(root)
root.mainloop()

【讨论】:

有没有办法重定向标准输入?

以上是关于如何将标准输出重定向到 Tkinter Text 小部件的主要内容,如果未能解决你的问题,请参考以下文章

如何将 A 的标准输出重定向到 B 的标准输入,将 B 的标准输出重定向到 A 的标准输入?

linux学习第一周;标准输入输出和错误重定向与管道

如何从Tkinter,Python中的Text小部件中移除焦点

如何将标准输出重定向到 CMD 中的程序?

如何将标准输出和标准错误重定向到 Python 中的记录器

如何将标准输出和标准错误重定向到 Python 中的记录器