立即将 stdout 重定向到 tkinter(无需等待进程完成) [英] Redirecting stdout to tkinter immediately (without waiting for the process to complete)

查看:31
本文介绍了立即将 stdout 重定向到 tkinter(无需等待进程完成)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个 Python 应用程序来获取用户的一些输入并根据这些输入调用一个 shell 脚本.

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

这个 shell 脚本可以运行很长时间,我想将它产生的输出(实时)重定向到 tkinter.我设法做到了,但它只在 shell 脚本完全完成后发生,而不是在 shell 脚本回声"例如某些东西时发生.

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.

所以主要问题:1. 仅在退出 shellScript.sh 后,输出才会出现在文本小部件中(尽管如果我在终端中手动运行相同的内容,我会看到连续输出).2. 附带问题:输出中打印的所有\n"都只是打印为\n",并且文本小部件中没有添加新行.

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.

这是我所拥有的:

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

推荐答案

由于 p.communicate() 会等待进程完成,所以使用 p.poll()code> 和 p.stdout.readline() 代替.也把进程放在一个线程中,避免阻塞主线程:

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

这篇关于立即将 stdout 重定向到 tkinter(无需等待进程完成)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆