2014-07-11 2 views
0

GUI 소프트웨어를 프로그래밍하는 중 외부 프로그램의 출력을 실시간으로 표시하는 터미널 창 (wxCtrl)이 있습니다.pexpect 긴 bash 명령 실행 wxpython GUI

서브 프로세스를 시도했습니다. 실행 중일 때 내 GUI가 멈추고 실행이 끝난 후 출력 만 제공되기 때문에이 작업이 예상대로 작동하지 않습니다. 내가 pexpect를 사용하기 위해 노력하고있어 이제

def miExecuteCmd(self, cmd): 
    self.terminal.addText("\n###\n\n") 
    self.terminal.addText("Executing: %s\n" % cmd) 
    args = shlex.split(cmd) 
    p = subprocess.Popen(args, stdout = subprocess.PIPE) 
    output = p.stdout.readlines() 
    output = "".join(output) 
    self.terminal.addText(output) 
    if (p.returncode != None and p.returncode != 0): 
     self.terminal.addText("Command Execution Problem, return code is %d\n" % p.returncode) 
    return output 

, 나는이 글을 읽고

how to use pexpect to get spontaneous output of subprocess in python 그래서 뭔가 같은

def miExecuteCmd(self, cmd): 
    self.terminal.addText("\n###\n\n") 
    self.terminal.addText("Executing: %s\n" % cmd) 
    output = [] 
    child = pexpect.spawn(cmd) 
    while True: 
     try: 
      child.expect('\n') 
      line = child.before 
      output.append(line) 
      self.terminal.addText(line) 
     except pexpect.EOF: 
      break 
    if child.exitstatus != None and child.exitstatus != 0: 
     line = "Command Execution Problem, return code is %d\n" % child.exitstatus 
     self.terminal.addText(line) 
     output.append(line) 

    output = "".join(output) 

    return output 

코딩하지만 오래 사용하면서 여전히 GUI는 동결 cmd를 실행하는 시간.

그래서 간단한 GUI 솔루션을 사용하여 GUI를 조작하고 동시에 cmd 출력을 볼 수 있습니다.

pexpect 문서를 읽었습니다. pexpect.spawn()이 명령에 분리 된 스레드를 시작해야하는 것처럼 보입니다. 이제 새로운 스레드에 pexpect.spawn()을 넣을 지 혼란 스럽습니다.

답변

0

마지막으로 wxPython에서 내 문제, GUI 고정 및 통신 스레딩을위한 훌륭한 솔루션을 만들었습니다.

http://www.blog.pythonlibrary.org/2010/05/22/wxpython-and-threads이 기사를 읽어야합니다. thread 통신 문제를 해결하기 위해 threading, wx.CallAfter(), PubSub의 조합입니다. 그래서 제 경우에는 pexpect를 추가하여 통신 할 대상을 지정하십시오.

여기에 내 run() 예제가 있습니다. 위의 링크에서 예제를보아야합니다.

def run(self): 
     wx.CallAfter(self.sendToMainThread, "\n###\n\n") 
     text = "Executing: %s\n" % (self.cmd) 
     wx.CallAfter(self.sendToMainThread, text) 

     child = pexpect.spawn(self.cmd) 
     while True: 
      try: 
       if self.stopFlag: 
        line = "Stop Buttont Clicked, Stopping External Command... \n" 
        wx.CallAfter(self.sendToMainThread, line) 
        child.terminate(True) 
        child.close() 
        break 
       child.expect('\n') 
       line = child.before 
       wx.CallAfter(self.sendToMainThread, line) 
      except pexpect.EOF: 
       child.close() 
       break 
     if child.exitstatus != None and child.exitstatus != 0: 
      line = "Command Execution Problem, return code is %d\n" % child.exitstatus 
      wx.CallAfter(self.sendToMainThread, line) 
     #it looks like next line never happens because of the exception handling above. 
     #child.close() make sure child return a code. 
     elif child.exitstatus == None: 
      line = "Command Execution was interrupted.\n" 
      wx.CallAfter(self.sendToMainThread, line) 

     #sending an end signal to main thread. command is finished. 
     wx.CallAfter(Publisher().sendMessage, "endthread", True) 
1

스크립트를 실행하는 데 사용하는 방법에 관계없이 GUI 창이 고정됩니다. GUI가 차단되지 않도록 명령을 별도의 스레드로 실행해야합니다. 그것은 당신이 당신의 코드의 최소한의 예를 제공 한 경우에 도움이 있지만, 어쨌든이 같은 시도 할 것 : 다시 새 스레드에서 명령을 실행 할 self.on_execute를 호출하는 이벤트 처리기 바인드한다

import thread 

def miExecuteCmd(self, cmd): 
    #bunch of codes... 

def on_execute(self, cmd): 
    thread.start_new_thread(self.miExecutecmd,()) 

+0

코드를 사용해 주셔서 감사합니다.하지만이 작업이 완료되지 않았습니다. 새 스레드가 주 스레드에게 정보를주고받을 필요가 있습니다. 나는 wxpython에서 PubSub을 사용하여 그것을 알아 냈고 곧 업데이트 할 것이다. –

+0

이전에 언급했다면 나는 그 사실을 보여줄 수도있었습니다! – user2963623