我有代码在子进程中执行外部文件。在我的主代码中,我将stdout指向TextCtrl。如何重定向外部文件的输出,以便将其输出到TextCtrl?
import wx, sys
from threading import Thread
import time
import subprocess
class mywxframe(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None)
pnl = wx.Panel(self)
szr = wx.BoxSizer(wx.VERTICAL)
pnl.SetSizer(szr)
szr2 = self.sizer2(pnl)
szr.Add(szr2, 1, wx.ALL|wx.EXPAND, 10)
log = wx.TextCtrl(pnl, -1, style= wx.TE_MULTILINE, size = (300, -1))
szr.Add(log, 0, wx.ALL, 10)
btn3 = wx.Button(pnl, -1, "Stop")
btn3.Bind(wx.EVT_BUTTON, self.OnStop)
szr.Add(btn3, 0, wx.ALL, 10)
self.CreateStatusBar()
redir = RedirectText(log)
sys.stdout=redir
szr.Fit(self)
self.Show()
def sizer2(self, panel):
sizer = wx.BoxSizer(wx.HORIZONTAL)
self.tc2 = wx.TextCtrl(panel, -1, 'Set Range', size = (100, -1))
btn2 = wx.Button(panel, -1, "OK",)
self.Bind(wx.EVT_BUTTON, self.OnStart, btn2)
sizer.Add(self.tc2, 0, wx.ALL, 10)
sizer.Add(btn2, 0, wx.ALL, 10)
return sizer
def OnStart(self, event):
self.p=subprocess.Popen(["C:\Python27\python.exe",'P:\Computing and networking\Python\Learning programs\hello_world.py'])
def OnStop(self, event):
self.p.terminate()
def write(self, *args):
print args
class RedirectText(object):
def __init__(self, aWxTextCtrl):
self.out=aWxTextCtrl
def write(self, string):
(self.out.WriteText, string)
app = wx.App()
frm = mywxframe()
app.MainLoop()
我尝试了以下内容:
def OnStart(self, event):
self.p=subprocess.Popen(["C:\Python27\python.exe",'P:\Computing and networking\Python\Learning programs\hello_world.py'], stdout=subprocess.PIPE)
while True:
output = self.p.stdout.readline()
wx.Yield()
if output =="":
pass
else:
print output
if not output: break
self.p.wait()
但它阻止了GUI,在执行完成之前不打印,并且它不会打印到TextCtrl。帮助
答案 0 :(得分:0)
如果您的子进程正在创建文件,则需要打开该文件并将行读入TextCtrl。如果子进程正在打印到stdout并且需要一段时间,则需要有一个侦听器线程来监视子进程的标准输出。
此示例不包含您已有的重定向内容,但由于您要从线程打印,因此需要使用wx.CallAfter
调用TextCtrl更新。
# spawn the new process, and redirecting stdout and stderr into this process
proc = subprocess.Popen([PathToCurrentPythonInterpreter, pyFilePath],stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE, bufsize=1)
proc.stdin.close()
#create new stdout and stderr stream listener objects
m=StreamWatcher()
n=StreamWatcher()
#create new threads for each listener, when the listener hears something it prints it to the GUI console log area
proc1 = Thread(target=m.stdout_watcher, name='stdout-watcher', args=('STDOUT', proc.stdout))
proc1.daemon=True
proc1.start()
proc2 = Thread(target=n.stderr_watcher, name='stderr-watcher', args=('STDERR', proc.stderr))
proc2.daemon=True
proc2.start()
class StreamWatcher:
def stdout_watcher(self, identifier, stream):
#for line in stream:
for line in iter(stream.readline,b''):
print line
if not stream.closed:
stream.close()
print "-i- Thread Terminating : ", identifier,"\n"
def stderr_watcher(self, identifier, stream):
#for line in stream:
for line in iter(stream.readline,b''):
#print (identifier, line)
print "-e- %s" % line
if not stream.closed:
stream.close()
print "-i- Thread Terminating : ", identifier, "\n"