이벤트루프란 무엇인가?
지난 포스팅에서 QWidget으로 빈 창을 만드는 간단한 예제를 같이 따라해보았습니다.
코드설명 중간에 "app.exec_()를 실행하면 이벤트루프가 시작된다"라는 표현을 사용했습니다. 그리고, "이 명령어를 실행하는 시점에서 우리가 만든 GUI 윈도우가 반응하고 움직이기 시작합니다."라고 말씀드렸는데, 이 이벤트루프에 대해서 조금만 자세히 다루고자 이 포스팅을 남깁니다.
이 개념에 대한 이해가 중요한 이유는, 모든 Qt GUI가 항상 이 방식으로 동작하기 때문입니다.
단, 다른 프로그래밍언어나 모듈을 통해 이벤트루프의 개념이 익숙한 분이라면 이 포스팅을 읽지 않으셔도 됩니다.
1. Qt의 이벤트루프와 QApplication
모든 Qt 프로그램은 QApplication이라는 클래스를 통해 상호작용할 수 있게 됩니다. 상호작용이란 게 거창한 게 아니라 어떤 키를 누르거나, 마우스를 클릭하고 드래그, 심지어는 마우스를 움직이기만 하는 동작 중에 프로그램이 반응할 수 있는 모든 작업들을 일컫는데요. 통상 하나의 입력작업을 편하게 "이벤트"라고 부릅시다. Qt 프로그램 안에서 이런 이벤트 정보들이 이벤트대기열, 즉 이벤트큐라는 메모리공간에 차곡차곡 쌓입니다. 그러면 QApplication이 계속해서 이벤트큐를 모니터링하다가 그 안에 처리되지 않은 이벤트가 있으면 순차적으로 처리합니다. 처리라는 게 거창한 게 아니고, 이벤트 종류별로 담당하는 각각의 매니저 같은 함수들을 보통 이벤트핸들러(혹은 listener)라고 부릅니다. 이벤트핸들러가 이벤트를 접수하고, 이벤트에 따른 상호작용의 결과를 내보내게 합니다. 이 때 프로그램이 반응하는 거죠. 그리고 이 때 일반적으로 한 개의 이벤트핸들러가 특정이벤트를 처리하기 위해 움직이는 동안 QApplication은 잠시 멈춰 있게 돼요. "작업이 완료되었습니다"라면서 이벤트핸들러가 작업을 마치는 시점에, 쉬고 있던 QApplication이 다시 모니터링을 시작하고, 이벤트 정보를 순차적으로 전달하는 일을 계속합니다. 이런 일련의 반복과정을 유식한 말로 이벤트루프(event loop)라고 부릅니다. 아주 빠르게 진행되기 때문에 동시작업 같아 보이지만 지극히 순차적으로 진행됩니다. 그리고 이와 관련하여 몇가지 룰이 있는데, 보통은 프로그램이 꼬이지 않게 하기 위해 이벤트루프를 Qt 프로그램당 하나씩만 둡니다. 이 말은 무조건 한 개의 이벤트핸들러만 움직일 수 있다(has control)는 뜻이기도 합니다. QApplication이 바로 이 이벤트루프를 담당하는 클래스입니다. 작업반장 같은 놈이예요.
2. 왜 app.exec()가 아니고 app.exec_()인가?
늘상 실행하는 명령어지만, 왜 언더바가 붙을까? 궁금하지 않으셨나요? 이게 히스토리가 좀 있는데, 사실 PyQt5를 사용하면서부터는 exec_() 대신 exec()를 사용하셔도 완전히 무방합니다. 파이썬에 여러개의 예약어(reserved keyword)가 있는데, exec도 그 중 하나였죠. 파이썬3부터는 exec가 빌트인함수로 변경되었습니다. print도 동일하게 예약어에서 빌트인함수로 변경된 케이스입니다. 그래서 현재는 이벤트루프를 시작하는 명령어를 굳이 exec_()를 사용하지 않고 exec()를 사용하셔도 되지만, PyQt4라든지 파이썬2.7이라든지 등 하위호환성을 위해(굳이?;;) 언더바를 붙이는 스타일을 유지하는 분들도 계시죠.
이와 마찬가지로 현재도 여전히 sys.exit(app.exec_()) 처럼 실행하시는 분들도 계신데, 이것 또한 Qt4와의 하위호환성 때문에 이렇게 쓰시는 경우가 많습니다. 혹은 손에 익어서 Qt5에서도 여전히 이 방식으로 작성하시는 경우일 수도 있겠고요. PySide2나 PyQt5 이후로는 app.exec()로 이벤트루프를 실행하실 수 있으며 아무 문제 없습니다.
이번 포스팅은 여기서 마치겠습니다.
도움이 되었다면, 혹은 질문이나 제안이 있다면, 언제든 좋아요와 댓글로 여러분의 의견을 표현해 주시면 감사하겠습니다.
그럼 다음포스팅에서 뵙겠습니다.
행복한 하루 되세요!
참고한 사이트
국내 유일의 파이썬+한컴오피스 업무자동화 입문강의
'GUI 튜토리얼 > PySide6 # Qt의 원조가 돌아왔다!' 카테고리의 다른 글
1. QMainWindow를 소개드리기 전에, QPushButton만 더 설명드리고... (2) | 2021.03.20 |
---|---|
[3/?] PySide6에서 가장 기초가 되는 QApplication과 QWidget (8) | 2021.03.19 |
[2/?] Pythonic에 집착하는 분들을 위한 Pyside6 팁[feat. __feature__] (2) | 2021.03.18 |
댓글