2011-10-18 2 views
1

내가 버튼도파이썬 Tkinter를이 : 서브 프로세스 사이의 업데이트 GUI는

I를 누르면라고합니다 (다른 매개 변수)를 .cmd 파일을 여러 번 호출하는 GUI

class App: 
    def process(self): 
     for filename in os.listdir(path): 
      subprocess.call(['script.cmd', filename]) 
      self.output('processed ' + filename) 

    def output(self, line): 
     self.textarea.config(state = NORMAL) 
     self.textarea.tag_config("green", background="green", foreground="black") 
     self.textarea.insert(END, line, ("green")) 
     self.textarea.yview(END) 
     self.textarea.config(state = DISABLED) 
     self.textarea.update_idletasks() 

root = Tk() 
app = App() 
app.build_gui(root) 
app.pack_gui(root) 

root.mainloop() 

과정을() 프로그램 호출 시도한 subprocess.Popen()와 오래된 os.spawnv() 그것은 항상 동일합니다. 파일을 처리 할 때 GUI가 반응하지 않습니다. 모든 파일이 처리 된 후에 만 ​​GUI는 모든 '처리 된 XYZ'메시지로 업데이트됩니다.

모든 하위 프로세스 호출 후에 update_idletasks()가 GUI를 업데이트하지 않아야합니까?

당신에게

편집 감사합니다 나는이 간단한 코드에 문제를 좁혀 : 스크립트가 제대로 작동하는지

from Tkinter import * 
import subprocess 

file_list = ['file1', 'file2', 'file3', 'file4', 'file5'] 

def go(): 
    labeltext.set('los') 
    for filename in file_list: 
     labeltext.set('processing ' + filename + '...') 
     label.update_idletasks() 

     proc = subprocess.call(["C:\\test\\process.exe", filename]) 
    labeltext.set('all done!') 


root = Tk() 

Button(root, text="Go!", command=go).pack(side=TOP) 

labeltext = StringVar() 
labeltext.set('Press button to start') 

label = Label(root, textvariable=labeltext) 
label.pack(side=TOP) 

root.mainloop() 

지금은 process.exe에 따라 달라집니다. busy-looping (예 : process.exe : int i = 0; (i < 1e9) {i ++;})의 소스 코드와 같은 간단한 C 프로그램을 작성하면 모든 file1-5로 GUI가 업데이트됩니다. 사용하던 원래 .exe 파일을 호출하면 "file1 처리 중"이라는 메시지가 표시되고 "file2 처리 중"으로 전환되지만 프로그램이 종료 될 때까지 정지됩니다 ("모두 완료되었습니다!").

나는 정말로 여기에서 무엇을 이해하지 못한다. 분명히 그것은 호출 된 프로세스와 관련이 있습니다. 누구나 아이디어가 있습니까?

+0

텍스트 영역의 업데이트로 충분해야합니다. 한 가지 질문은 복사 - 붙여 넣기 오류 일 수도 있지만 'app = App()'이 '루트'를 참조하지 않는 이유는 무엇입니까? 전체 코드를 붙여 넣을 수 있습니까? –

+0

답변 해 주셔서 감사합니다. 불행히도 충분하지 않은 것 같습니다. 처리 중에 GUI가 갱신되지 않습니다. App()은 생성자 함수가 없기 때문에 루트를 참조하지 않습니다. 이게 꼭 필요한거야? 전체 코드는 꽤 길지만 제일 중요한 부분은 첫 번째 게시물에 포함되어 있다고 생각합니다. – Timedog

+0

MMh,이게 상쾌하지 않은 이유는 모르겠지만, http://infohost.nmt.edu/tcc/help/pubs/tkinter/universal.html을 보면, 라벨을 업데이트하는 것이 확실하지 않습니다. 텍스트는 소위 유휴 작업입니다. 'StringVar'를 사용하지 않고 테스트 할 수 있습니까?'label.configure (text = "processing ")'? –

답변

2

더러운 해결책을 찾았습니다 : 모든 subprocess.call() 전에 root.update()를 호출합니다.

에는 버튼을 처리하는 동안 누르지 있는지 확인하려면이 서브 프로세스는 다음과 같이

시작하기 전에, 내가 그들 모두를 비활성화 (즉 root.update() 빠른 구글 검색에 따라 문제가 될 것 같습니다) :

from Tkinter import * 
import subprocess 

file_list = ['file1', 'file2', 'file3', 'file4', 'file5'] 

def button(): 
    b_process.configure(state=DISABLED) 
    go() 
    b_process.configure(state=NORMAL) 

def go(): 
    for filename in file_list: 
     label.configure(text="processing " + filename) 
     root.update() 

     proc = subprocess.call(["C:\\DTNA\\stat\\run.exe", filename]) 
     print 'process terminated with return code ' + str(proc)  
    label.configure(text="all done!") 

root = Tk() 

b_process = Button(root, text="Go!", command=button) 
b_process.pack(side=TOP) 

label = Label(root, text='Press button to start') 
label.pack(side=TOP) 

root.mainloop() 
관련 문제