2015-01-02 4 views
2

저는 프로그래밍과 Python을 처음 접했고 계산기 응용 프로그램을 연습하고 있습니다. 파이썬 2.7에서 Tkinter를 사용하고 있습니다. 응용 프로그램에는 예상대로 다양한 버튼이 있으며 숫자/결과를 보여주는 Entry 및 Label 위젯이 있습니다.Python tkinter mainloop이 창을 닫을 때 종료하지 않습니다.

내 프로그램이 mainloop을 시작하지만 창을 닫아도 mainloop이 멈추지 않는다고 생각합니다. after 루프를 추가하기 전에 정상적으로 작동 했으므로 이후에는 문제가 있다고 가정합니다. 나는 또한 wait_variable을 사용하고있다.

내 코드를 살펴보고 조언을 할 수 있다면 매우 감사 할 것입니다. 주요 내용을 포함 시켰습니다. 위젯을 작성하고 사용자 입력/결과 출력을 처리하는 코드는 다른 파일 (버튼, 디스플레이, 입력)에 있지만 잘하면 사용자가 없으면 이해할 수 있습니다.

import Tkinter as tk 
# These contain the other bits of code 
import Buttons as bt 
import Displays as ds 
import Inputs as ip 


class MainWindow(tk.Frame): 
    def __init__(self, parent): 
     tk.Frame.__init__(self, parent) 
     self.parent = parent 
     self.parent.title("Calculator") 

     # Making frames to fill with widgets 
     self.displays_frame = tk.Frame(parent) 
     self.displays_frame.grid(padx=10, pady=10) 
     self.buttons_frame = tk.Frame(parent) 
     self.buttons_frame.grid() 
     # Initialising the widgets and user input functions 
     self.display = ds.Displays(self.displays_frame) 
     self.button = bt.Button(self.buttons_frame) 
     self.input = ip.Inputs() 

    def take_inputs(self, parent): 
     self.parent = parent 

     # This waits for a button to be pressed 
     self.wait_variable(self.button.button_pressed) 
     # On a button press, its value is inserted into display Entry box/result is put in Label 
     # Both self.button.button_pressed above and self.display.r below are StringVars 
     self.input.process_input(self.button.button_pressed, self.display.entry_box, self.display.r) 
     # Using after here so it keeps waiting for button presses to be recorded 
     self.after(100, self.take_inputs, self.parent) 

def main(): 
    root = tk.Tk() 
    app = MainWindow(root) 
    # Here the wait_variable and after functions are called 
    app.take_inputs(root) 
    # The below string is printed after the first button has been pressed 
    print "main, now starting mainloop" 
    root.mainloop() 
    # "finished" is never printed 
    print "finished" 

if __name__ == '__main__': 
    main() 

내가 대신 주회 돌이를 사용하는 내 자신의 이벤트 핸들러를했습니다 가정, 나는이 take_inputs 방법에 self.parent.protocol("WM_DELETE_WINDOW", self.end(parent))를 추가하려고 않았다, 그래서 주회 돌이를 실행하지 않고 모든 것을 종료 할 수있다. self.end 함수는 MainWindow 클래스에 추가 한 메소드로 "closing now"를 출력 한 다음 프로그램을 종료하거나 파괴했습니다.

그러나 내가 여기에 넣은 기능은 이고 즉시 실행되었습니다. "WM_DELETE_WINDOW"이 올바르게 조회되지 않았습니다 ("WM_DELETE_WINDOW"대신 "foo"가 오류를주지 않음).

도움 주셔서 감사합니다.

+1

왜 자신 만의 이벤트 처리기를 만들고 있습니까? tkinter가 이벤트를 처리하는 방법에있어 잘못된 점은 무엇입니까? –

+0

윈도우 닫기는 메인 루프와 프로세스를 종료한다고 생각합니다. 순수 GUI 응용 프로그램에서는 인쇄 할 수있는 곳이 없습니다. 오른쪽 사이드 바에있는 관련 질문 및 답변을 읽는 것이 좋습니다. –

+0

안녕하세요, Terry, 답장을 보내 주셔서 감사합니다. 이것은 순수한 GUI 응용 프로그램이 아니므로 명령문이 터미널에 인쇄됩니다. after와 wait_variable을 추가하기 전에 창을 닫을 때 주 루프가 종료되었음을 나타내는 "finished"를 성공적으로 인쇄했습니다. 내가 여기에 찾을 수있는 모든 가능성이 보이는 질문을 읽었습니다. 왜 wm_protocol 메서드를 추가하려했으나 설명 된대로 작동하지 않았습니다. –

답변

0

나는 wait_variable을 사용하지 않고 코드를 다시 작성했습니다. 문제는 윈도우 닫는 것이 wait_variable을 통과하지 못했기 때문에 코드가 mainloop에 결코 돌아 가지 않는다는 것입니다.

다음은 새로운 take_inputs 메소드입니다. button.button_go은 False로 먼저 정의 된 부울 변수이지만 마우스 클릭에 바인딩 된 단추의 일부로 True로 설정됩니다 (표시되지 않음).

def take_inputs(self, parent): 
    self.parent = parent 

    # button.button_go is immediately set to False on updating the display box 
    if self.button.button_go == True: 
     self.input.process_input(self.button, self.display.entry_box, self.display.r) 
     self.button.button_go = False 
    self.after(100, self.take_inputs, self.parent) 

after() 메소드는 예상대로 mainloop과 잘 어울립니다. wait_variable에 대한 수치심. 그것은 청초하게 들렸지 만 외관상으로는 아주 유용하지 않다.

wm_protocol "WM_DELETE_WINDOW"정의가 작동하지 않는 이유를 모르겠습니다!

관련 문제