如何将stdout重定向到Tkinter Text小部件(How to redirect stdout to a Tkinter Text widget)

系统教程 行业动态 更新时间:2024-06-14 17:03:54
如何将stdout重定向到Tkinter Text小部件(How to redirect stdout to a Tkinter Text widget)

我的基本程序从脚本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小部件,在这里看到它的行动:-)

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

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)

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: invalid command name "".33328904.33329104"""

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


EDIT:

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主循环,因此直到退出循环时才会执行它之前的语句。 但是,一旦你退出主循环,你尝试使用文本部件,但它已经被销毁了。

我建议你将调用移动到main到Tkinter小部件的回调(我想你已经试图用app.button_press() )来做到这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()

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.

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()

更多推荐

本文发布于:2023-04-24 14:23:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/dzcp/b82d1f90e56580dec8cfe2c46d404fc8.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:如何将   部件   重定向   stdout   Tkinter

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!