当前位置: 首页 > 面试题库 >

Python多重处理将子进程的标准输出重定向到Tkinter文本

南门朗
2023-03-14
问题内容

我正在尝试使用Tkinter GUI启动子进程并将其stdout / stderr输出显示到Text小部件。最初,我认为可以通过设置“ sys.stdout
= text_widget”轻松将sys.stdout重定向到Text小部件,但似乎不行。出现错误:“文本实例没有属性’flush’”。

我在线检查并得到了一些解决方案,例如使用队列与子进程进行通信。但是,由于我的特殊要求,它们都不适合我的情况:

  1. 子进程最好由“ multiprocessing.Process”启动,因为使用共享变量会更容易,这使得子进程解决方案变得可用。
  2. 子进程的代码已经存在,里面有很多“打印”,所以我不想将它们修改为“ Queue.put()”之类的东西。

在这种情况下,谁能解决获得“ multiprocessing.Process”的“ print”输出并显示为Tkinter Text的解决方案?非常感谢!

我的情况的示例代码如下:

import sys
import time
from multiprocessing import Process
from Tkinter import *

def test_child():
    print 'child running'

def test_parent():
    print 'parent running'
    time.sleep(0.5)
    Process(target=test_child).start()

def set_txt(msg):
    gui_txt.insert(END, str(msg))
    gui_txt.see(END)

if __name__ == '__main__':
    gui_root = Tk()
    gui_txt = Text(gui_root)
    gui_txt.pack()
    gui_btn = Button(gui_root, text='Test', command=test_parent)
    gui_btn.pack()

    gui_txt.write = set_txt
    sys.stdout = gui_txt

    gui_root.mainloop()

问题答案:

仍然可以使用队列而不必摆脱所有print语句。您可以使用Process从属stdout重定向来执行此操作。下面的解决方案使用Queue子类来模仿stdout。然后,该线程由一个线程监视,该线程寻找被泵送到文本小部件中的新文本。

import sys
import time
from multiprocessing import Process
from multiprocessing.queues import Queue
from threading import Thread
from Tkinter import *

# This function takes the text widget and a queue as inputs.
# It functions by waiting on new data entering the queue, when it 
# finds new data it will insert it into the text widget 
def text_catcher(text_widget,queue):
    while True:
        text_widget.insert(END, queue.get())

# This is a Queue that behaves like stdout
class StdoutQueue(Queue):
    def __init__(self,*args,**kwargs):
        Queue.__init__(self,*args,**kwargs)

    def write(self,msg):
        self.put(msg)

    def flush(self):
        sys.__stdout__.flush()


def test_child(q):
    # This line only redirects stdout inside the current process 
    sys.stdout = q
    # or sys.stdout = sys.__stdout__ if you want to print the child to the terminal
    print 'child running'

def test_parent(q):
    # Again this only redirects inside the current (main) process
    # commenting this like out will cause only the child to write to the widget 
    sys.stdout = q                                                                                                                                                                                                                                                         
    print 'parent running'
    time.sleep(0.5)
    Process(target=test_child,args=(q,)).start()

if __name__ == '__main__':
    gui_root = Tk()
    gui_txt = Text(gui_root)
    gui_txt.pack()
    q = StdoutQueue()
    gui_btn = Button(gui_root, text='Test', command=lambda:test_parent(q),)
    gui_btn.pack()

    # Instantiate and start the text monitor
    monitor = Thread(target=text_catcher,args=(gui_txt,q))
    monitor.daemon = True
    monitor.start()

    gui_root.mainloop()


 类似资料:
  • 问题内容: 我的基本程序从脚本GUI.py导入了它的GUI界面。 在我的GUI.py中: 但是它的作用是打开两个窗口,第一个窗口 (顶层 窗口 ) 按预期工作,第二个窗口 处于空闲状态 , 这是期望的,直到我单击某个按钮 ,该 按钮 在连续按下后打印数据,并且打印的数据应出现在第二个窗口的文本小部件中, 但是 不会发生,程序也没有响应,当我关闭“顶层”窗口时,会出现错误消息 “ TclError:

  • 问题内容: 在bash中,调用将在stdout上显示该命令的任何输出。 调用会将该命令的任何输出重定向到指定的文件(在本例中为“输出”)。 有没有一种方法可以将输出重定向到文件 并 在stdout上显示? 问题答案: 您想要的命令名为 : 例如,如果您只关心标准输出: 如果要包括stderr,请执行以下操作: 将通道2(stderr /标准错误)重定向到通道1(stdout /标准输出),以便将两

  • 问题内容: 我想从Groovy程序中执行foo.bat,并将生成的进程的输出重定向到stdout。Java或Groovy代码示例都可以。 foo.bat可能需要花费几分钟才能运行并生成大量输出,因此我希望在生成后立即查看输出,而不是必须等到该过程完成之后才能立即查看所有输出。 问题答案: 它使用一个类读取执行的程序生成的所有输出,并将其显示在其自己的stdout中。

  • 我试图将Spring Boot日志重定向到log4j2,但我看不出配置中缺少什么。 请注意,在A和B之间,在下面的图片1中,状态日志如何包含我想要的模式中的一些日志条目,但有些不包含。 图片中的“MYCONFIG” 我所追求的是在Spring Boot启动后自定义日志的格式。 图1-控制台输出: 图2-log4j2。属性文件 到目前为止,我所看到的是:https://logging.apache.

  • 问题内容: 是否可以在Python中临时重定向stdout / stderr(即在方法期间)? 编辑: 当前解决方案的问题(我最初记得但后来忘记了)是它们没有 重定向 ;相反,它们只是完全替换了流。因此,如果某个方法由于某种原因(例如,由于将流作为参数传递给某物)而具有该变量的 本地 副本,则该方法将无效。 有什么办法吗? 问题答案: 要解决某些函数可能已将流作为局部变量缓存的问题,因此替换全局变

  • 问题内容: 我正在从另一个python脚本(A)调用python脚本(B)。 使用subprocess.call,如何将B的标准输出重定向到指定的文件? 我正在使用python 2.6.1。 问题答案: 将文件作为参数传递给: