立即将 stdout 重定向到 tkinter(无需等待进程完成) [英] Redirecting stdout to tkinter immediately (without waiting for the process to complete)
问题描述
我正在编写一个 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屋!