본문 바로가기
ОКБ (실험 설계국)/Trouble Shooting

14. [Python] tkinter로 생성한 Window 창 x버튼 클릭 시 동작 설정

by Rosmary 2022. 1. 19.
728x90
반응형

 

 

 

 

필자가 요즘 진행하고 있는 프로젝트에서 Python의 tkinter 모듈을 매인으로 사용하고 있다. 무려 작년 5월부터 진행하려 했던 프로젝트지만, 밀리고 밀리다 새해가 되어서야 시작하게 된 프로젝트인만큼, 관련 공부를 계속 진행하고 있는 상황이다.

 

대략 이런 거(?) 만드는 것이라 보면 된다.

 

이제 겨우 로그인 창 모양과 동작만 어느정도 흉내낼 정도로 만들어놓긴 했는데, 한 가지 고민거리가 생겼다.

 

서두에 링크를 걸어놓은 포스팅을 보면 알겠지만, 프로그램 자체가 워낙 민감한 정보를 담고 있다보니, 하나의 계정이 프로그램에 중복 로그인하는 것을 방지하고자 한다. 따라서, 매인 창에서 로그아웃 버튼을 누르면, 창이 닫히면서 계정과 관련된 특정 파일에서 "xxx 계정이 로그아웃 되었다는" 표식을 남기려는 작업을 진행 중이다.

 

그런데, tkinter로 생성한 창으로 몇 번 테스트를 진행하다보니, 로그아웃 버튼을 누르지 않고, 창 우측 위의 X 버튼을 클릭하여 창을 닫을 경우, 컴퓨터는 Python이 강제 종료된 것이라 판단하여 로그아웃 버튼을 눌렀을 때 동작해야하는 함수들을 하나도 실행하지 않는다. 만약, 누군가가 로그인을 했다가 X를 눌러 창을 닫는다면, 그 사람은 다시 로그인을 하지 못하는 참사가 벌어지게 되는 것이라 반드시 해결이 필요한 문제다.

 

말로는 어려우니, 아래의 gif을 보자.

 

exit_window 함수 내 print() 코드 대신, 로그를 기록하는 코드가 작성되어 있다고 가정하면 된다.

 

다행히 필자와 같은 고민을 한 사람들이 매우 많았는지, 인터넷에서 쉽게 답을 찾을 수 있었다.

 

https://stackoverflow.com/questions/3295270/

 

Overriding Tkinter "X" button control (the button that close the window)

When the user presses a close Button that I created, some tasks are performed before exiting. However, if the user clicks on the [X] button in the top-right of the window to close the window, I can...

stackoverflow.com

 

 

내용을 보니, Tk() 클래스 내에 protocol()이라는 매서드가 있는데, 해당 매서드는 생성한 윈도우 창을 제어하는 기능을 하는 모양이다. 사용 시 인자로 윈도우 창을 제어하는 프로토콜(WM Protocol이라고 한다) 이름과, 프로토콜 제어 진행 시작 시 동작시킬 함수를 지정해주면 된다.

 

Tk().protocol(WM Protocol, 동작할 함수명)

 

창 제어 프로토콜은 WM_이라는 이름으로 시작하는데, 이는 window manager를 뜻한다. 왠지 모르게 프로토콜 종류가 많을 것이라 생각했는데, 막상 검색해보니 tkinter에서는 아래의 3가지만 주로 사용하는 듯 하다.

 

- WM_DELETE_WINDOW

- WM_SAVE_YOURSELF

- WM_TAKE_FOCUS

 

이 중 창 닫힘 제어와 관련있는 WM 프로토콜 이름은 WM_DELETE_WINDOW다 (나머지는 찾아봤는데, 필자 실력의 한계인지 도저히 무슨 말인지 모르겠다). 따라서, 필자는 protocol() 매서드의 인자로 WM_DELETE_WINDOW를 지정하고 button의 command와 동일한 함수를 하나 복사한 뒤, 이름만 변경하여 protocol에 의해 동작할 함수명으로 정의했다.

아래 gif의 15번째 줄 함수와 28번째 코드를 참고하자.

 

 

 

테스트 해 본 결과, button과 동일한 command를 공유하는 것은 불가능했는데,

- window.protocol('WM_DELETE_WINDOW', exit_window) - 아직까지 그 이유를 찾지 못했다. 함수를 중복으로 사용할 경우, bind를 해야하는지 테스트 해 봐야 할 듯 하다. 혹시라도 중복 함수를 사용할 수 있는 방법을 찾게 된다면 해당 내용도 포스팅으로 작성할 예정이다.

 

 

 

 

Fin.

반응형

댓글