一个长时间运行的shell脚本生成stdout和stderr,我想在GUI中的textctrl上显示它.这可以使用线程并将GUI线程与shell脚本的线程分开.然而,当我实现多处理时,我遇到了障碍.这是我的下载代码:#!/usr/bin/env pythonimpor...

一个长时间运行的shell脚本生成stdout和stderr,我想在GUI中的textctrl上显示它.这可以使用线程并将GUI线程与shell脚本的线程分开.然而,当我实现多处理时,我遇到了障碍.这是我的下载代码:
#!/usr/bin/env python
import wx
import sys, subprocess
from multiprocessing import Process, Queue
from Queue import Empty
class MyFrame(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self.button = wx.Button(self, -1 , "Run")
self.output = wx.TextCtrl(self, -1, '', style=wx.TE_MULTILINE| wx.TE_READONLY|wx.HSCROLL)
self.Bind(wx.EVT_BUTTON, self.OnButton, self.button)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.output, -1, wx.EXPAND, 0)
sizer.Add(self.button)
self.SetSizerAndFit(sizer)
self.Centre()
def OnButton(self, event):
numtasks = 4 # total number of tasks to run
numprocs = 2 # number of processors = number of parallel tasks
work_queue = Queue()
for i in xrange(numtasks):
work_queue.put(i)
processes = [Process(target=self.doWork, args=(work_queue, ))
for i in range(numprocs)]
for p in processes:
p.daemon = True
p.start()
def doWork(self, work_queue):
while True:
try:
x = work_queue.get(block=False)
self.runScript(x)
except Empty:
print "Queue Empty"
break
def runScript(self, taskno):
print '## Now Running: ', taskno
command = ['./script.sh']
proc = subprocess.Popen(command, shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
while True:
stdout = proc.stdout.readline()
if not stdout:
break
#sys.stdout.flush() #no need for flush, apparently it is embedded in the multiprocessing module
self.output.AppendText(stdout.rstrip()) #this is the part that doesn't work.
if __name__ == "__main__":
app = wx.App(0)
frame = MyFrame(None, title="shell2textctrl", size=(500,500))
frame.Show(True)
app.MainLoop()
我已经根据别人的建议尝试了很多解决方案.其中包括:使用wx.CallAfter或wx.lib.delayedresult使GUI响应;几个线程配方(例如,wxApplication Development Cookbook,threadpool,其他……)并让multiprocess()从一个单独的线程运行;重新定义sys.stdout.write以写入textctrl;等等.他们都没有成功.任何人都可以提供解决方案和工作代码吗?您可以在这里使用此脚本编写我遗忘的人:
#!/bin/tcsh -f
@ i = 1
while ($i <= 20)
echo $i
@ i += 1
sleep 0.2
end
解决方法:
我不知道这是否会对你有所帮助,但我在这里使用子进程有这样的例子:
http://www.blog.pythonlibrary.org/2010/06/05/python-running-ping-traceroute-and-more/
请参阅pingIP和tracertIP方法.如果您的shell脚本是用Python编写的,那么您可以添加某种类型的生成器,就像我在该文章中使用的那些发布回GUI一样.您可能已经阅读过LongRunningProcess wiki文章,但我接受了这个并在此处制作了自己的教程:
http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads/
本文标题为:如何在wxPython TextCtrl中捕获在单独进程中运行的shell脚本的输出?


基础教程推荐
- Python之多进程(multiprocessing)学习:创建进程,join方法 2023-11-13
- python之Linux基础(三) 2023-09-04
- 如何使用python自动执行shell输入? 2023-11-15
- Python requirements.txt安装用法介绍 2023-10-08
- 如何在Python中通过管道传递Python进程的输出? 2023-11-14
- 详解TensorFlow训练网络两种方式 2023-08-11
- Linux环境安装python3 2023-09-04
- 如何在Python中的多进程中解决“AttributeError:__ exit__”问题? 2023-11-15
- 如何使用PySpark加载IPython shell 2023-11-16
- Python WindowsError:[错误3]尝试重命名时系统找不到指定的文件 2023-11-14