Python multiprocessing redirect stdout of a child process to a Tkinter Text -


i'm trying use tkinter gui launch child process , display stdout/stderr output text widget. initially, thought sys.stdout can redirected text widget setting "sys.stdout = text_widget" seems not. comes error: "text instance has no attribute 'flush'".

i checked online , got solutions, using queue communicate child process. however, none of them fit case because of special requirement:

  1. the child process should better launched "multiprocessing.process" because easier use shared variables, makes subprocess solutions usable.
  2. the codes of child process there quite lot "print" inside, don't want modify them "queue.put()" or else.

in case, come solution of getting "multiprocessing.process"'s "print" output , display tkinter text? many thanks!

an example code of case follows:

import sys import time multiprocessing import process 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() 

it still possible use queues without having rid of of print statements. can use process dependent stdout redirect this. solution below uses queue subclass mimic stdout. queue monitored thread looks new text gets pumped text widget.

import sys import time multiprocessing import process multiprocessing.queues import queue threading import thread tkinter import *  # function takes text widget , queue inputs. # functions waiting on new data entering queue, when  # finds new data insert text widget  def text_catcher(text_widget,queue):     while true:         text_widget.insert(end, queue.get())  # queue behaves 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):     # line redirects stdout inside current process      sys.stdout = q     # or sys.stdout = sys.__stdout__ if want print child terminal     print 'child running'  def test_parent(q):     # again redirects inside current (main) process     # commenting out cause child write 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 , start text monitor     monitor = thread(target=text_catcher,args=(gui_txt,q))     monitor.daemon = true     monitor.start()      gui_root.mainloop() 

Comments

Popular posts from this blog

php - render data via PDO::FETCH_FUNC vs loop -

c++ - OpenCV Error: Assertion failed <scn == 3 ::scn == 4> in unknown function, -

The canvas has been tainted by cross-origin data in chrome only -