2011-11-28 4 views
0

다음과 같은 경우, 실시간으로 텍스트 widget에 temp2 스크립트 (하위 프로세스를 통해 실행 됨)의 모든 출력을 인쇄하려고합니다.Python/Tkinter : 루프 반복이 완료되지 않았습니다.

제가 직면 한 문제는 temp2에서 i <= 468에 대해 스크립트가 정상적으로 작동하고 있으며 실시간으로 표시됩니다.

그러나 내가 i = 469 이상을 넣으면 완료없이 많은 반복 후에 실행이 중단됩니다.

예를 들어 i = 469의 경우 로그 파일에는 i = 469에서 i = 3까지의 항목이 있습니다. 거기서 모든 과정이 멈춘다.

참고 :i = 469은 컴퓨터에서 다를 수 있습니다. i = 469이 잘 작동하면 더 높은 값을 시도하십시오.

Temp1.py가 주 스크립트입니다.

#temp1.py 
from Tkinter import * 
import Tkinter as tk 
import os 
import ttk 
os.system('echo OS ready') 
os.system('chmod 755 *') 
import subprocess 
import sys 

#Creating new Window to display output 
t = Tk() 
t.title('output Run Display') 
t.geometry('800x1000-5+40') 
t.state('normal') 
little = Label(t, text="NRUNTEST OUTPUT LOG").grid(column = 0, row = 0) 
log = Text(t, state='disabled', width=115, height=150, wrap='none') 
log.grid(row = 1, column = 0) 

test=subprocess.Popen('temp2',shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE) 


#stdout 
while True: 
    line_out = test.stdout.readline() 
    line_er = test.stderr.readline() 
    if line_out == "" and line_er == "": 
     break 
    else: 
     log['state'] = 'normal' 
     log.insert('end', line_out) 
     log.insert('end', line_er) 
     log['state'] = 'disabled' 
     print line_out 
     print line_er 
     t.update() 
t.mainloop() 

그리고 아래는 제가 서브 프로세스를 실행하고있는 스크립트입니다. 처리가 중지하고 반환되는 데이터 avalilable의 새로운 라인이있는 경우에만 다시 시작을 의미하는 -

#temp2 #csh script 

set i = 469 
while ($i > 0) 
    echo i is $i | tee -a log 
    set i = `expr "$i" - 1` 
end 
+1

'else :'행이 정확하게 들여 쓰기되어 있습니까? 또한 아래 줄은 유효하지 않은 것으로 보입니다 ... – eumiro

+0

내 통역사에서 괜찮 았는데 여기 유닉스에서 창 기계로 복사 붙여 넣기로 인한 들여 쓰기 오류가 수정되었습니다 – Ani

답변

0
import os 
import ConfigParser 
from Tkinter import * 
import Tkinter as tk 
import os 
import ttk 
os.system('echo OS ready') 
os.system('chmod 755 *') 
import subprocess 
from subprocess import call 
import sys 

os.system('rm stdout') 

#Creating new Window to display output 
t = Tk() 
t.title('output Run Display') 
t.geometry('100x100') 
t.state('normal') 
little = Label(t, text="NRUNTEST OUTPUT LOG").grid(column = 0, row = 0) 
log = Text(t, state='disabled', width=50, height=50, wrap='none') 
log.grid(row = 1, column = 0,sticky=(N,W,E,S)) 
s = ttk.Scrollbar(t,orient=VERTICAL,command=log.yview) 
s.grid(column=1,row=1,sticky=(N,S)) 
log.configure(yscrollcommand=s.set) 
ttk.Sizegrip().grid(column=1, row=1, sticky=(S,E)) 

with open("stdout","wb") as out: 
    with open("stderr","wb") as err: 
     test=subprocess.Popen('tem',shell=True,stdout=out,stderr=err) 
fout = open('stdout','r') 
ferr = open('stderr','r') 
def verify(): 

    data_out = fout.readlines() 
    data_out = ''.join(data_out) 

    log['state'] = 'normal' 
    log.insert('end',data_out) 
    log['state'] = 'disabled' 
    #print data_out 

    t.after(1000,verify) 
    fout.close() 

verify() 

t.mainloop() 
1

귀하의 문제는 test.stdout.readline에 대한 호출이 차단된다는 점이다.

물론 test.stderr.readline에 대해서도 마찬가지입니다.

당신이 원하는 것을 다루는 가장 간단한 방법은 파일 시스템에있는 파일에 서브 프로세스를 쓰는 것입니다. 주 프로세스에서 해당 파일을 열고 정기적으로 호출되는 tkinter 콜백 함수 안에서 읽어보십시오. .after tkinter 메소드.

(witha의 당신이 파일의 마지막에 당신이 있는지 확인하는 seektell 방법을 사용할 수 있습니다 파일 시스템에 파일) 코드에서 당신이 예로서 배치하는 것이

주, Tkinter.mainloop에 전화에만 도달 하위 프로세스가 이미 제거 된 후에

더 나은 해결책은 쉘 스크립트에 의존하지 않고 원하는 모든 로그를 파이썬에서 읽는 것입니다.

Tkinter.after는 javascript의 settimeout과 비슷합니다. 위젯 (예 : "t"객체)의 메소드이며 대기 할 시간 (밀리 초)과 호출 할 함수의 이름을 전달합니다 -

처럼은 jsbueno 답변으로

def verify_output(): 
    # read subprocess output file and update the window if needed 
    ... 
    # call self after 1 second 
    t.after(1000, verify_output) 

# callreader callback for the first time: 

t.after(10, verify_output) 
Tkinter.mainloop() 
+0

고마워요. 당신의 조언이 도움이되었습니다. – Ani

0

, 당신은 문제가 readline에 전화를 차단에서 온다. 대신 파일 이벤트 소스를 사용하여 데이터가 사용 가능할 때 알림을받을 수 있습니다 (createfilehandler tkinter 메소드를 통해). 자세한 내용은 this previous answer을 참조하십시오.

관련 문제