如何在wxPython TextCtrl中捕获在单独进程中运行的Shell脚本的输出?

如何在wxPython TextCtrl中捕获在单独进程中运行的Shell脚本的输出?,第1张

如何在wxPython TextCtrl中捕获在单独进程中运行的Shell脚本的输出

我找到了一个解决方案,该解决方案在Roger Stuckey的Simpler wxPython Multiprocessing
Example
框架之上实现了修改后的输出Queue
。下面的代码比他的代码还要简单。也可以将其清除一点。希望它可以帮助别人。我仍然有na的感觉,尽管应该有一种更直接的方法来做到这一点。

import getopt, math, random, sys, time, types, wx, subprocessfrom multiprocessing import Process, Queue, cpu_count, current_process, freeze_supportfrom Queue import Emptyclass Myframe(wx.frame):    def __init__(self, parent, id, title):        wx.frame.__init__(self, parent, id, title, wx.Point(700, 500), wx.Size(300, 200))        self.panel = wx.Panel(self, wx.ID_ANY)        #widgets        self.start_bt = wx.Button(self.panel, wx.ID_ANY, "Start")        self.Bind(wx.EVT_BUTTON, self.OnButton, self.start_bt)        self.output_tc = wx.TextCtrl(self.panel, wx.ID_ANY, style=wx.TE_MULTILINE|wx.TE_READONLY)        # sizer        self.sizer = wx.GridBagSizer(5, 5)        self.sizer.Add(self.start_bt, (0, 0), flag=wx.ALIGN_CENTER|wx.LEFT|wx.TOP|wx.RIGHT, border=5)        self.sizer.Add(self.output_tc, (1, 0), flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM, border=5)        self.sizer.AddGrowableCol(0)        self.sizer.AddGrowableRow(1)        self.panel.SetSizer(self.sizer)        # Set some program flags        self.keepgoing = True        self.i = 0        self.j = 0    def onButton(self, event):        self.start_bt.Enable(False)        self.numtasks = 4        self.numproc = 2        #self.numproc = cpu_count()        self.output_tc.AppendText('Number of processes = %dn' % self.numproc)        # Create the queues        self.taskQueue = Queue()        self.outputQueue = Queue()        # Create the task list        self.Tasks = range(self.numtasks)        # The worker processes...        for n in range(self.numproc): process = Process(target=self.worker, args=(self.taskQueue, self.outputQueue)) process.start()        # Start processing tasks        self.processTasks(self.update)        if (self.keepgoing): self.start_bt.Enable(True)    def processTasks(self, resfunc=None):        self.keepgoing = True        # Submit first set of tasks        numprocstart = min(self.numproc, self.numtasks)        for self.i in range(numprocstart): self.taskQueue.put(self.Tasks[self.i])        self.j = -1 # done queue index        self.i = numprocstart - 1 # task queue index        while (self.j < self.i): # Get and print results self.j += 1 output = None while output != 'STOP!':     try:         output = self.outputQueue.get()          if output != 'STOP!':   resfunc(output)     except Empty:         break if ((self.keepgoing) and (self.i + 1 < self.numtasks)):     # Submit another task     self.i += 1     self.taskQueue.put(self.Tasks[self.i])    def update(self, output):        self.output_tc.AppendText('%s PID=%d Task=%d : %sn' % output)        wx.YieldIfNeeded()    def worker(self, inputq, outputq):        while True: try:     tasknum = inputq.get()     print '## Now Running: ', tasknum #this goes to terminal/console. Add it to outputq if you'd like it on the TextCtrl.     command = ['./script.sh']     p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)     while True:         r = p.stdout.readline()         if not r:  outputq.put('STOP!')  break         outputq.put(( current_process().name, current_process().pid, tasknum, r.rstrip())) except Empty:     break    # The worker must not require any existing object for execution!    worker = classmethod(worker)class MyApp(wx.App):    def onInit(self):        self.frame = Myframe(None, -1, 'stdout to GUI using multiprocessing')        self.frame.Show(True)        self.frame.Center()        return Trueif __name__ == '__main__':    freeze_support()    app = MyApp(0)    app.MainLoop()


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5617641.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-15
下一篇 2022-12-15

发表评论

登录后才能评论

评论列表(0条)

保存