2017-07-24 358 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

出於某種原因,它仍然在漫長的等待之後立即顯示所有內容。我只是希望用戶能夠看到輸出實時,因爲它是一個漫長的過程,不希望他們認爲沒有任何東西在運行。這是我想要實時的唯一原因。另外,非常感謝你幫助我一樣! :) –

相關問題