2009-05-18 3 views
1

Tcl/Tk examples?에 대한 내 대답과 동일한 wxPython을 찾고 있습니다. 특히, 여러 버튼을 만드는 방법에 대한 예를보고 싶습니다. 각 버튼은 클릭 할 때 외부 명령을 실행합니다. 프로세스가 실행되는 동안 출력을 스크롤 가능한 wxPython 위젯으로 이동합니다.wxPython : 명령을 비동기 적으로 실행하여 텍스트 위젯에 stdout 표시

프로세스가 실행되는 동안 GUI가 차단되어서는 안됩니다. 예를 들어, 단추 중 하나가 단위 테스트 빌드 또는 실행과 같은 개발 작업을 시작할 수 있다고 가정합니다. 버튼을 클릭하면

답변

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

이것은 내 기준 중 하나를 충족하지 않습니다 : "프로세스가 실행되는 동안 GUI가 차단되어서는 안됩니다". 귀하의 예제에서 out.read()가 완료 될 때까지 기다리는 동안 UI가 차단됩니다. –

+0

브라이언은 왜 그렇게 말합니까? 너 해봤 어? 나의 이해는 Popen.wait()을 사용하여 블록을 차단할 수 있지만 wait 명령을 사용하여 블록하지 않으면 read 명령을 사용하여 그 당시 사용 가능한 stdout을 읽을 수 있습니다. http://docs.python.org/library/subprocess.html –

+0

브라이언 (Bryan),이 비단뱀의 내용은 생각보다 훨씬 쉽습니다 ... Tk보다 훨씬 쉽습니다. –

관련 문제