2009-05-18 31 views
1

私はTcl/Tk examples?の私の答えに相当するwxPythonを探しています。具体的には、いくつかのボタンを作成する方法の例を見たいと思います。それぞれのボタンは、クリックするといくつかの外部コマンドを実行します。プロセスが実行されている間、出力をスクロール可能なwxPythonウィジェットに移動します。wxPython:コマンドを非同期で実行し、stdoutをテキストウィジェットに表示

プロセスが実行されている間、GUIはブロックされません。たとえば、ボタンの1つが単体テストの構築や実行のような開発タスクを開始すると仮定します。

答えて

5

完全な実例です。

import wx 
import functools 
import threading 
import subprocess 
import time 

class Frame(wx.Frame): 
    def __init__(self): 
     super(Frame, self).__init__(None, -1, 'Threading Example') 
     # add some buttons and a text control 
     panel = wx.Panel(self, -1) 
     sizer = wx.BoxSizer(wx.VERTICAL) 
     for i in range(3): 
      name = 'Button %d' % (i+1) 
      button = wx.Button(panel, -1, name) 
      func = functools.partial(self.on_button, button=name) 
      button.Bind(wx.EVT_BUTTON, func) 
      sizer.Add(button, 0, wx.ALL, 5) 
     text = wx.TextCtrl(panel, -1, style=wx.TE_MULTILINE|wx.TE_READONLY) 
     self.text = text 
     sizer.Add(text, 1, wx.EXPAND|wx.ALL, 5) 
     panel.SetSizer(sizer) 
    def on_button(self, event, button): 
     # create a new thread when a button is pressed 
     thread = threading.Thread(target=self.run, args=(button,)) 
     thread.setDaemon(True) 
     thread.start() 
    def on_text(self, text): 
     self.text.AppendText(text) 
    def run(self, button): 
     cmd = ['ls', '-lta'] 
     proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
     for line in proc.stdout: 
      wx.CallAfter(self.on_text, line) 

if __name__ == '__main__': 
    app = wx.PySimpleApp() 
    frame = Frame() 
    frame.Show() 
    app.MainLoop() 
+0

これは役に立つ例ですが、私の質問で言及したTkの例と同じではありません。この例では、外部コマンドを実行したいと言う私の要求の部分を無視します。はい、あなたの例から外挿するのはかなり簡単ですが、この例に遭遇する初心者がそれを理解できるかどうかはわかりません。質問を投稿することで私の希望は(wxPythonのスピードを上げるためにすぐに登場する以外に)両方の言語で同じ小さなアプリケーションを表示することでした。とにかくありがとう。 –

+0

サブプロセスの起動をリファクタリングします。 – FogleBird

0

スタートボタンをクリックしたスレッド:

try: 
    r = threading.Thread(target=self.mycallback) 
    r.setDaemon(1) 
    r.start() 
except: 
    print "Error starting thread" 
    return False 

使用wx.PostEventとwx.lib.neweventメインスレッドへのコールバックからメッセージを送信します。

このlinkが役立つ場合があります。ボタンが押されたときに

import subprocess, sys 

def doit(cmd): 
    #print cmd 
    out = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True).stdout 
    return out.read() 

だから、コマンドはサブプロセスモジュールを使用して実行します、そしてあなたは、文字列として出力を得る:

+0

私はあなたの助言に感謝しますが、私はwxPythonを使用した具体的な例を探しています。私がwxPythonについて全く何も知っていないとすれば、あなたは真実に非常に近いでしょう。 –

0

ブライアンは、このような何かを試してみてください。テキストコントロールの値に割り当てることで表示できます。テキストを徐々に表示するには、out.readfully()または複数回の読み込みが必要な場合があります。

ボタン&のテキストフィールドが使い慣れていない場合は、wxPython demoを簡単に見てください。

+0

これは私の基準の1つを満たしていません。「プロセスが実行されている間にGUIがブロックされるべきではありません。あなたの例では、out.read()が完了するまでUIがブロックされます。 –

+0

あなたはブライアンとは何を言いますか?あなたはそれを試しましたか?私の理解では、Popen.wait()を実行することでブロックすることができますが、waitコマンドでブロックしないと、その時点でreadコマンドで使用可能なstdoutを読み込むことができます。 http://docs.python.org/library/subprocess.html –

+0

ブライアン、このpythonのものは、あなたが考えるよりもはるかに簡単です...あなたがチャンスを与えれば、Tkよりもさらに簡単です。 –

関連する問題