2014-07-09 5 views
0

root.after_idle()을 설정하면 Toplevel이 작동하지 않습니다.Tkinter after_idle이 최상위를 죽입니다.

from Tkinter import * 
blah=1 

def afterloop(): 
    label.config(text=str(blah)) 
    root.after(500,afterloop) 

def idleloop(): 
    global blah 
    blah=blah+1 
    if blah<500000: 
     root.after_idle(idleloop) 

def second(): 
    spam=Toplevel() 
    button2=Button(spam,text="Button 2",command=spam.destroy) 
    button2.pack() 

root=Tk() 
button1=Button(root,text="Press to Open",command=second) 
button1.pack() 
label=Label(root,text="*********************") 
label.pack() 
root.update() 
root.after_idle(idleloop) 
root.after(500,afterloop) 
root.mainloop() 

after_idle이 활성화되어있는 동안 Toplevel은 실행되지 않습니다. 예를 들어> 500000 (컴퓨터 속도에 맞게 조정)이 예상대로 작동하기 시작합니다. 문서를 읽는 방법, after_idle은 할 일이 없을 때만 실행해야합니다. 이 경우 Toplevel의 처리를 차단하는 것으로 보입니다.

idletask는 머시닝 센터에서 데이터를 읽고 쓰는 매우 큰 상태 기계입니다. 나는 누군가가 내가 root.after()를 사용하도록 제안 할 것을 안다. 나는 다른 목적으로. 이 코드는 문제를 설명하기위한 것입니다. 이것은 Toplevel이 호출 될 때까지 내가 원하는 것에 완벽하게 작동합니다. 유휴 작업은 결국 500000을 치고 멈 추면 계속 실행 중임을 알 수 있습니다.

idletask를 별도의 스레드로 이동할 수 있지만이 시점에서는 매우 바람직하지 않습니다.

답변

1

after_idle을 사용하는 잘못된 방법입니다. 적어도 호출에 1 밀리 초가 필요합니다. 그렇지 않으면 이벤트 루프가 다른 이벤트를 처리 할 기회를 얻지 못합니다. 유휴 상태를 처음 확인한 후 유휴 콜백 목록을 봅니다. 거기에 뭔가가 있다면, 그것을 호출합니다. 그런 다음 더 이상 수행 할 작업을 찾고 콜백 목록이 비어있을 때까지 계속됩니다. 그런 다음에 만 정상적인 이벤트를 처리합니다.

그러나 작업 목록에 계속 추가 할 것이므로 유휴 프로세스는 효과적으로 자신의 꼬리를 추적합니다. 하나의 항목을 꺼내 큐에 넣습니다. 그런 다음 해당 항목을 꺼내 큐에서 푸시하는 등의 작업을 수행합니다. 유휴 상태가 될 때해야 할 일의 무한한 목록을 효과적으로 가지고 있으며 통제권을 포기하기 전에 모든 일을 시도합니다.

+0

좋아요, 완전히 이해합니다. 그것은 두 가지 더 질문을 남겨 둡니다. 루트 창에서 위젯이 계속 작동하는 이유는 무엇입니까? 더 중요한 것은, after_idle은 mainloop()을 통해 그 패스에 할 일이 전혀 없다면 호출된다는 것입니다. – Burtski

관련 문제