2017-07-24 355 views
0

我正在使用wxPython创建一个GUI。我试图从subprocess.Popen到TextCtrl一次显示一行结果。由于存在大量的信息,窗口在完全显示所有内容之前经历了“不回应”阶段。我也在使用线程。 我已经尝试了poll,read(),readline(),itr,并且输出仍然一次显示,而不是逐行显示在窗口的简短NOT RESPONDING阶段之后。如果有人能够帮助我解决这个问题,那将会很棒。谢谢!如何从子流程标准输出获得结果并在TextCtrl中实时显示它们? (Python 2.7 - wxPython)

+0

正如我们不知道它是什么你正在做的请阅读https://stackoverflow.com/help/mcve –

回答

0

如果你是在一个线程中运行subprocess,那么你只需要一个参考传递给您的文本控件到线程,然后使用wxPython中的线程安全的方法之一,如wx.CallAfter调用文本控件的write方法。这里有一个非常简单的例子:

import subprocess 
import time 
import wx 

from threading import Thread 


class PingThread(Thread): 

    def __init__(self, text_ctrl): 
     Thread.__init__(self) 
     self.text_ctrl = text_ctrl 
     self.sentinel = True 
     self.start() 

    def run(self):    
     proc = subprocess.Popen("ping www.google.com", 
            shell=True, 
            stdout=subprocess.PIPE) 
     while self.sentinel: 
      line = proc.stdout.readline() 
      if line.strip() == "": 
       pass 
      else: 
       wx.CallAfter(self.text_ctrl.write, line) 

      if not line: break 

     proc.kill() 


class MyFrame(wx.Frame): 

    def __init__(self): 
     wx.Frame.__init__(self, None, title='Redirecter') 
     self.ping_thread = None 

     main_sizer = wx.BoxSizer(wx.VERTICAL) 

     panel = wx.Panel(self) 

     self.log = wx.TextCtrl(panel, style=wx.TE_MULTILINE) 

     ping_btn = wx.Button(panel, label='Ping') 
     ping_btn.Bind(wx.EVT_BUTTON, self.on_ping) 

     main_sizer.Add(self.log, 1, wx.ALL|wx.EXPAND, 5) 
     main_sizer.Add(ping_btn, 0, wx.ALL, 5) 
     panel.SetSizer(main_sizer) 

     self.Bind(wx.EVT_CLOSE, self.on_close) 

     self.Show() 

    def on_ping(self, event): 
     self.ping_thread = PingThread(self.log) 

    def on_close(self, event): 
     if self.ping_thread: 
      self.ping_thread.sentinel = False 
      self.ping_thread.join() 
     self.Destroy() 


if __name__ == '__main__': 
    app = wx.App(False) 
    frame = MyFrame() 
    app.MainLoop() 

您可以通过以下链接了解更多关于wxPython的和线程:

+0

这是一个很好的例子@MikeDriscoll。未答复问题已解决:D。我想知道是否有一种方法来实时显示stdout? –

+0

这将会非常接近实时。你有什么理由需要它比这更快? –

+0

出于某种原因,它仍然在漫长的等待之后立即显示所有内容。我只是希望用户能够看到输出实时,因为它是一个漫长的过程,不希望他们认为没有任何东西在运行。这是我想要实时的唯一原因。另外,非常感谢你帮助我一样! :) –

相关问题