<i id='B9kPL'><tr id='B9kPL'><dt id='B9kPL'><q id='B9kPL'><span id='B9kPL'><b id='B9kPL'><form id='B9kPL'><ins id='B9kPL'></ins><ul id='B9kPL'></ul><sub id='B9kPL'></sub></form><legend id='B9kPL'></legend><bdo id='B9kPL'><pre id='B9kPL'><center id='B9kPL'></center></pre></bdo></b><th id='B9kPL'></th></span></q></dt></tr></i><div id='B9kPL'><tfoot id='B9kPL'></tfoot><dl id='B9kPL'><fieldset id='B9kPL'></fieldset></dl></div>

      <tfoot id='B9kPL'></tfoot>

        <small id='B9kPL'></small><noframes id='B9kPL'>

          <bdo id='B9kPL'></bdo><ul id='B9kPL'></ul>
      1. <legend id='B9kPL'><style id='B9kPL'><dir id='B9kPL'><q id='B9kPL'></q></dir></style></legend>
      2. Python 多处理将子进程的标准输出重定向到 Tkint

        时间:2023-05-26

          <legend id='3cqUz'><style id='3cqUz'><dir id='3cqUz'><q id='3cqUz'></q></dir></style></legend>

          1. <small id='3cqUz'></small><noframes id='3cqUz'>

            <i id='3cqUz'><tr id='3cqUz'><dt id='3cqUz'><q id='3cqUz'><span id='3cqUz'><b id='3cqUz'><form id='3cqUz'><ins id='3cqUz'></ins><ul id='3cqUz'></ul><sub id='3cqUz'></sub></form><legend id='3cqUz'></legend><bdo id='3cqUz'><pre id='3cqUz'><center id='3cqUz'></center></pre></bdo></b><th id='3cqUz'></th></span></q></dt></tr></i><div id='3cqUz'><tfoot id='3cqUz'></tfoot><dl id='3cqUz'><fieldset id='3cqUz'></fieldset></dl></div>
            • <bdo id='3cqUz'></bdo><ul id='3cqUz'></ul>

            • <tfoot id='3cqUz'></tfoot>
                <tbody id='3cqUz'></tbody>

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

                  问题描述

                  限时送ChatGPT账号..

                  我正在尝试使用 Tkinter GUI 来启动子进程并将其 stdout/stderr 输出显示到 Text 小部件.最初,我认为 sys.stdout 可以通过设置sys.stdout = text_widget"轻松重定向到文本小部件,但似乎不是.报错:Text instance has no attribute 'flush'".

                  I'm trying to use Tkinter GUI to launch a child process and display it stdout/stderr output to a Text widget. Initially, I thought the sys.stdout can be easily redirected to the Text widget by setting "sys.stdout = text_widget" but seems not. It comes to an error: "Text instance has no attribute 'flush'".

                  我在网上查了一下,得到了一些解决方案,比如使用队列与子进程通信.但是,由于我的特殊要求,它们都不适合我的情况:

                  I checked online and got some solutions, like using a Queue to communicate with the child process. However, none of them fit my case because of my special requirement:

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

                  在这种情况下,任何人都可以找到获得multiprocessing.Process"的打印"输出并显示到 Tkinter Text 的解决方案吗?非常感谢!

                  In this case, could anyone come to a solution of getting a "multiprocessing.Process"'s "print" output and display to a Tkinter Text? Many thanks!

                  我的案例的示例代码如下:

                  An example code of my case is a follows:

                  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.然后,该队列由一个线程监视,该线程会寻找被注入到文本小部件中的新文本.

                  It is still possible to use queues without having to get rid of all of your print statements. You can use a Process dependent stdout redirect to do this. The solution below uses a Queue subclass to mimic stdout. That queue is then monitored by a thread that looks for new text that gets pumped into the text widget.

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

                  这篇关于Python 多处理将子进程的标准输出重定向到 Tkinter 文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:input() 正在阻止进程的使用 下一篇:如何从 Process- 或 Thread 实例返回值?

                  相关文章

                  最新文章

                • <small id='3yLrq'></small><noframes id='3yLrq'>

                    <bdo id='3yLrq'></bdo><ul id='3yLrq'></ul>
                  1. <tfoot id='3yLrq'></tfoot>
                    <i id='3yLrq'><tr id='3yLrq'><dt id='3yLrq'><q id='3yLrq'><span id='3yLrq'><b id='3yLrq'><form id='3yLrq'><ins id='3yLrq'></ins><ul id='3yLrq'></ul><sub id='3yLrq'></sub></form><legend id='3yLrq'></legend><bdo id='3yLrq'><pre id='3yLrq'><center id='3yLrq'></center></pre></bdo></b><th id='3yLrq'></th></span></q></dt></tr></i><div id='3yLrq'><tfoot id='3yLrq'></tfoot><dl id='3yLrq'><fieldset id='3yLrq'></fieldset></dl></div>
                  2. <legend id='3yLrq'><style id='3yLrq'><dir id='3yLrq'><q id='3yLrq'></q></dir></style></legend>