如何将stdout重定向到Tkinter Text小部件

时间:2013-08-29 17:11:42

标签: python python-2.7 tkinter stdout

我的基础程序从脚本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)

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

  

“TclError:命令名称无效”“.33328904.33329104”“”

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


编辑:

为了帮助你,如果你在努力解决这个问题,我已经制作了一个脚本,将stdout重定向到Tkinter Text小部件,在行动here中看到它: - )

1 个答案:

答案 0 :(得分:6)

问题是,当你调用app.mainloop()时,线程正在忙于执行Tkinter主循环,因此在你退出循环之前,它之前的语句不会被执行。但是一旦退出mainloop,就会尝试使用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()