Redirecting stdout to tkinter immediately (without waiting for the process to complete)

别说谁变了你拦得住时间么 提交于 2021-02-05 11:26:30

问题


I am writing a python app to take some inputs from the user and call a shell script based on these inputs.

This shell script can run for quite sometime, and I want to redirect the output it produces (in realtime) to tkinter. I managed to do that, but it only happens after the shell script is completely finished, not as soon as the shell script "echos" something for example.

So main problem: 1. Output appears in the text widget only after shellScript.sh is exited (although if I run the same in the terminal manually, I see continuous output). 2. Side problem: all the "\n" printed in the output are just printed as "\n" and no new lines are added in the text widget.

here is what I have:

class RedirectText(object):
   def __init__(self, text_ctrl):
       """Constructor"""
       self.output = text_ctrl

   def write(self, string):
       self.output.insert(tk.END, string[2:])

class Gui(GuiApp):
   def __init__(self, master=None):
      redir = RedirectText(self.text_Output)
      sys.stdout = redir

  def testRun(self, event=None):
     p = subprocess.Popen(["./shellScript.sh"], stdout=subprocess.PIPE)
     print(p.communicate()[0])

回答1:


As p.communicate() will wait for the process to complete, so use p.poll() and p.stdout.readline() instead. Also put the process in a thread to avoid blocking the main thread:

import threading
...
class Gui(GuiApp):
    ...
    def runScript(self):
        print('started')
        p = subprocess.Popen(['./shellScript.sh'], stdout=subprocess.PIPE, bufsize=1, text=True)
        while p.poll() is None: # check whether process is still running
            msg = p.stdout.readline().strip() # read a line from the process output
            if msg:
                print(msg)
        print('finished')

    def testRun(self, event=None):
        # create a thread to run the script
        threading.Thread(target=self.runScript, daemon=True).start()


来源:https://stackoverflow.com/questions/62163329/redirecting-stdout-to-tkinter-immediately-without-waiting-for-the-process-to-co

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!