2011-07-13 22 views
1

私はコマンドラインユーティリティのGUIであるwxPythonのアプリケーションで作業しています。 GUIには、アプリケーションからの出力を表示するテキストコントロールがあります。私はサブプロセスを使用してシェルコマンドを起動していますが、完了するまでは出力がありません。wxPython、サブプロセスからリアルタイムで出力をキャプチャ

私はいくつかのソリューションを試しましたが、どれもうまくいかないようです。以下は、私は、現時点で使用しているコードです(更新):特に

 def onOk(self,event):   
     self.getControl('infotxt').Clear() 
     try: 
      thread = threading.Thread(target=self.run) 
      thread.setDaemon(True) 
      thread.start() 

     except Exception: 
      print 'Error starting thread'  

    def run(self):  
     args = dict() 
     # creating a command to execute... 

     cmd = ["aplcorr", "-vvfile", args['vvfile'], "-navfile", args['navfile'], "-lev1file", args['lev1file'], "-dem", args['dem'], "-igmfile", args['outfile']] 

     proc = subprocess.Popen(' '.join(cmd), shell=True, stdout=subprocess.PIPE, stderr.subprocess.PIPE)   

     print 
     while True: 
      line = proc.stdout.readline() 
      wx.Yield() 
      if line.strip() == "": 
       pass 
      else:     
       print line.strip()     
      if not line: break 
     proc.wait() 

class RedirectInfoText: 
    """ Class to redirect stdout text """ 
    def __init__(self,wxTextCtrl): 
     self.out=wxTextCtrl 

    def write(self,string): 
     self.out.WriteText(string) 

class RedirectErrorText: 
    """ Class to redirect stderr text """  
    def __init__(self,wxTextCtrl): 
     self.out.SetDefailtStyle(wx.TextAttr()) 
     self.out=wxTextCtrl 

    def write(self,string): 
     self.out.SetDefaultStyle(wx.TextAttr(wx.RED)) 
     self.out.WriteText(string) 

は私がプログレスバーを作成するために、リアルタイムでの出力を必要とするつもりです。

編集:Mike Driscollの提案に基づいてコードを変更しました。時々動作しているようですが、私は次のいずれかのエラーを取得していますほとんどの時間:

(のpython:7698):Gtkの-CRITICAL **:gtk_text_layout_real_invalidate: アサーション `レイアウト - > wrap_loop_count == 0'

または

(:7893パイソン):失敗のGtk-WARNING **:無効なテキストバッファイテレータ: イテレータが初期化されていない、または 内の文字/ pixbufs /ウィジェットのいずれかバッファはmイテレーターが作成されたので、odifiedされました。 の位置をバッファの変更を保存するために使用するには、マーク、文字番号、または行番号を使用する必要があります。あなたはタグを適用し、あなたのイテレータを無効にすることなく マークを挿入しますが、 「刃先交換式」バッファの内容(オフセット 文字によって参照できる内容)に影響を与える任意の突然変異は、すべての未処理のイテレータに セグメンテーションフォールトを(コアダンプ)無効になることができます

手がかりはありますか?

答えて

1

これは少しトリッキーなことができますが、私は、私がここで書いたそれを行うための一つの方法を考え出し:http://www.blog.pythonlibrary.org/2010/06/05/python-running-ping-traceroute-and-more/

テキストのリダイレクトを設定した後、あなたはこのような何かをする必要があります:

def pingIP(self, ip): 
    proc = subprocess.Popen("ping %s" % ip, shell=True, 
          stdout=subprocess.PIPE) 
    print 
    while True: 
     line = proc.stdout.readline() 
     wx.Yield() 
     if line.strip() == "": 
      pass 
     else: 
      print line.strip() 
     if not line: break 
    proc.wait() 

この記事では、テキストのリダイレクト方法も示しています。うまくいけばそれが助けになるだろう!

+0

ありがとう、この記事は役に立ちました。私はwxを推測しています.Yield()は私が行方不明だったものです。コードを更新しましたが、今はsegfaultsを取得しています。上記をご覧ください。 – jaho

+0

私のGtkの知識はかなり限られています。うまくいけば、ここのLinuxの人たちの一人が話してくれるでしょう。あるいは、wxPythonのメーリングリストに投稿することもできます。彼らはおそらく何が起こっているのか知っているだろう。 –

2

問題は、GUIスレッドからの更新ではなく、プロセスを実行しているスレッドのコンテキストから出力ウィジェットをwx.Yieldおよび更新しようとしているためです。

  1. あなたがスレッドからプロセスを実行しているので、あなたはGUIのスレッドをブロックしていない、ので、保留中のUIイベントはとにかく正常に処理されなければならないので、wx.Yieldを呼び出すする必要はありません。

  2. 非GUIスレッドから発生したプリントやその他の出力を処理する方法の例については、wx.PyOnDemandOutputWindowクラスを参照してください。

関連する問題