如何将标准输出重定向到 Tkinter 文本小部件 [英] How to redirect stdout to a Tkinter Text widget

查看:48
本文介绍了如何将标准输出重定向到 Tkinter 文本小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

My base program imports it's GUI interface from a script GUI.py

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 中:

In my 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这就是预计直到我单击某个按钮,该按钮在连续按下打印数据后,打印的数据应该出现在第二个窗口的文本小部件中但是这不会发生,并且没有响应程序,当我关闭 Toplevel 窗口时,会出现一条错误消息

But what It does is it opens two windows and the first window (the toplevel one) works as expected and the second is idle , This is what is expected until I click a certain button which after pressing prints data continuously and the data printed should appear in the second window's text widget however this doesn't happen and there is no response from the program and when I close the Toplevel window an error message appears

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

"TclError: invalid command name "".33328904.33329104"""

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

So How can I print the data in Text Widget rather than in the console?

为了帮助你解决这个问题,我制作了一个脚本来将 stdout 重定向到 Tkinter Text 小部件,查看它的实际效果 这里 :-)

Inorder to help ya'll if you struggling with this, I've made a script to redirect stdout to a Tkinter Text widget, see it in action here :-)

推荐答案

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

The problem is that when you call app.mainloop(), the thread is busy executing the Tkinter mainloop, so the statements before it are not executed until you exit the loop. But once you exit the mainloop, you try to use the Text widget but it is already destroyed.

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

I recommend you to move the call to main to the callback of a Tkinter widget (I suppose you are already trying to do that with app.button_press()), so the Text object can be used to display the 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 文本小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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