长时间运行的shell脚本会生成stdout和stderr,我想在GUI中的textctrl上显示stdout和stderr。这可以使用线程和从shell脚本的线程分离GUI线程。但是,当我实现多处理时,我遇到了障碍。这里是我的-stripped下调代码:如何在wxPython TextCtrl中捕获在独立进程中运行的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,线程池,其他...),并使多进程()从一个单独的线程运行;重新定义sys.stdout.write写入textctrl;和什么。他们都没有成功。任何人都可以提供一个解决方案和工作代码?你可以使用这个脚本写在这里的某个地方被我忘了谁:
#!/bin/tcsh -f
@ i = 1
while ($i <= 20)
echo $i
@ i += 1
sleep 0.2
end
事实上,我根本看LongRunningProcess文章,你的教程(非常有用!)。我可以让我的代码与_threading_一起工作,但不能与_multiprocessing_一起使用。这很愚蠢,因为多处理基于线程。然后再次理解这两个模块如何工作是非常有限的。不幸的是,我真的需要使用多处理。 – 2011-04-30 04:14:39
好的。我还没有使用过多处理,所以目前我无法对此进行评论。如果我找到一些时间,我会深入研究。 – 2011-04-30 14:01:33