2011-05-06 3 views
1

나는 python pygtk GUI에서 cdparanoia 명령 줄 유틸리티를 사용하고자하는 프로젝트에서 작업 중입니다. UI 개발을 위해 Glade를 사용하고 있습니다. 하위 프로세스 가져 오기 시도하고 subprocess.Popen 사용하여. 그것은 작동하지만 프로세스가 실행되는 동안 내 GUI가 멈 춥니 다 (창을 다시 칠할 수 없습니다). 사용자에게 아주 좋은 상호 작용이 아닙니다. 이 문제를 어떻게 방지 할 수 있습니까? 창에 취소 버튼을 달았 으면 좋겠지 만 프로그램이 "정지"되면 작동합니다. 궁극적으로, stderr를 캡처하고 싶습니다 (아래의 오디오 정보는 stdout을 통해 sox로 파이프됩니다). gtk로 제시하십시오. 사용자가 볼 수있는 프로그램을 설치할 때 Synaptic과 비슷한 모양으로 펼치십시오. 실시간으로 일어나는 일들. 또한 진행 표시기의 텍스트를 사용하여 실제 진행률 표시기 위젯을 작성하고 싶습니다. 프로세스가 완료되면 (모든 정보를 하나의 큰 정보 덤프로 제공함) 실시간으로 정보를 파이썬에 전달하는 방법은 무엇입니까?도움이 필요합니다 pygtk에서 실시간으로 STDOUT을 파이썬 프로젝트의 GUI로 캡쳐

실시간 정보를 캡처해야 할 때 해당 : 여기

Working on me - me - DISK 01.flac 
cdparanoia III release 10.2 (September 11, 2008) 

Ripping from sector  0 (track 1 [0:00.00]) 
     to sector 325195 (track 15 [1:56.70]) 

outputting to stdout 

(== PROGRESS == [>        | 004727 00 ] == :-) O ==) 

내가 지금까지 사용했던 코드 : 감사와

 quick = " -Z" if self.quick == True else "" 
     command = "cdparanoia -w%s 1- -| sox -t wav - \"%s - %s - DISK %s%s.flac\"" %\ 
        (
         quick, 
         self.book_name.replace(" ", "_"), 
         self.author_name.replace(" ", "_"), 
         "0" if disc < 10 else "", 
         disc 
        ) 
     print command 
     shell = subprocess.Popen(command, shell=True, executable="/bin/bash", 
            stdin=subprocess.PIPE, 
            stdout=subprocess.PIPE, 
            stderr=subprocess.PIPE 
           ) 
     data, err = shell.communicate(command) 

, Narnie

답변

2

을 내가 쓴 한 번 파이썬 셸 구현, 그리고 실행 된 wget 및 실제 파이썬 콘솔을 완벽하게 작동 outpu 티.

당신은 subprocess.Popen를 사용하고 sys.stdout에 직접 작성해야합니다 :

process = subprocess.Popen(shlex.split(command), stdout = subprocess.PIPE, stderr = subprocess.STDOUT) 
complete = False 

while True: 
    output = process.stdout.read(1) 

    if output == '' and process.poll() != None: 
    break 

    if output != '': 
    sys.stdout.write(output) 
    sys.stdout.flush() 
+0

합니다. 나는 셸 = True를 사용하고 있었고, 그렇게 생각한 것처럼 동작 시켰습니다. 모두 stderr (프로그램이 텍스트 출력을 보내는 곳)에서 작업 중이지만 진행률 표시 줄 텍스트는 캡처되지 않습니다. 어떤 아이디어? – narnie

+0

BTW, 나는 shlex shell 파서에 대해서도 배우는 것이 좋다. 전에는 몰랐고 훌륭하게 작동합니다! – narnie

1

당신이 파일 핸들에서 읽는 GUI 프로그램을 작성하는 경우에는 GUI 이벤트에 파일 기술자 이벤트를 통합 할 수있는 두 개의 사용 디스패처가 고리. 이벤트 루프에 대한 일반적인 설명은 Wikipedia에서 찾을 수 있습니다. Gtk +에 대한 구체적인 설명은 reference에서 찾을 수 있습니다.

문제의 해결책 : 기능 g_io_add_watch을 사용하여 동작을 기본 이벤트 루프에 통합하십시오. Here은 C의 한 예입니다. Python은 유사해야합니다.

0

예 여기에는 2 가지 문제가 있습니다. 첫 번째는 읽기 시간 제한을 지정해야하므로 하위 프로세스가 완료 될 때까지 차단하지 않기 때문입니다. 둘째로 버퍼링이 바람직하지 않은 일이 발생할 수 있습니다.

시간 초과로, 첫 번째 문제를 해결하고, 비동기 내 서브 프로세스 모듈을 시도 할 수있는 하위 과정에서 읽으려면 : http://www.pixelbeat.org/libs/subProcess.py 참고이 간단뿐만 아니라 과거와 리눅스에서만. 새로운 파이썬 서브 프로세스 모듈 의 기초로 사용되었으므로 이식성이 필요한 경우 더 잘 수행 할 수 있습니다.

이/이해 일어날 수있는 추가 버퍼링을 제어하려면, 참조 :이 내가 필요하고 무엇을의 라인을 따라입니다 http://www.pixelbeat.org/programming/stdio_buffering/

+0

팁 주셔서 감사합니다. 나는이 링크를 읽기를 열망한다. 다음의 모든 사람들에게 도움이되는이 유용한 http://faq.pygtk.org/index.py?file=faq23.020.htp&req=show도 발견했습니다.하지만 지금은 첫 번째 기술을 사용해 왔지만 더 완성 된 버전. – narnie

관련 문제