PyQt에서 Event와 Event Handling
PyQt도 다른 GUI application framework에서처럼 Event를 추상화한 Class를 제공하고, 이 Class를 Event의 다양한 종류에 따라 상속시킨 sub class를 제공한다.
QEvent
가 Event를 추상화한 class이다, 특정 Event가 발생시 Qt는 해당 Event를 추상화한 QEvent
의 subclass의 instance를 생성하고 해당 evnet의 종류에 따라 조금 다른 전달방식을 따르지만 결국은 이 instance를 해당 event를 처리할 QObject
instance에 event()
메서드를 통해 전달한다. event()
메서드에서 해당 event는 직접 처리되지는 않고 해당 evnet의 type에 따라 적절한 evnet handler가 호출되게 된다.
개발자는 PyQt가 제공하는 다양한 event들과 event handler를 이용하여 원하는 기능을 event handler에 추가하거나 아니면 아예 재작성하는 방식으로 Event를 처리할 수 있다. 이같은 방식을 Event Handling이라 한다. 하지만 PyQt는 signals and slots라는 또다른 방법으로 Event처리를 지원한다. PyQt가 제공하는 Signals and slots은 Event Handling를 내부적으로 사용하긴 하지만, 개발자 입장에서 내부적인 event handling mechanism에 대한 깊은 고려 없이 보다 쉽게 Event 처리를 가능하게 해준다. 사실 Signals and slots은 object간의 통신을 위해 개발된 방식으로 object간에 loosely coupling을 사용하면서도 효과적인 정보 교환이 가능하며 매우 쉽게 구현할 수 있기 때문에 PyQt에서 Event 처리에서 signals and slots이 훨씬 많이 사용된다.
Event 전달 방식 종류
PyQt에서 Event는 전달 방식에 따라 다음과 같은 3가지로 나뉜다.
- Spontaneous event : OS에 의해 발생. system queue에 push되며
QApplicaton
instance의exec()
메서드 호출시 시작되어 background로 반복 수행되고 있는 event loop에 의해 Pop되어 비동기 처리됨. - Posted event : Qt 또는 application(개발대상)에서 발생. Qt가 관리하는 Posted event들의 Queue에 Push되며,
QApplicaton
instance의exec()
메서드 호출시 시작되어 background로 반복 수행되고 있는 event loop에 의해 Pop되어 비동기 처리됨.. - Sent event : Qt 또는 application(개발대상)에서 발생. 발생 즉시 처리할 object로 보내져 동기 처리가 됨
OS에 의해 발생되는 event의 대표적인 예는 QMouseEvent, QKeyEvent가 있다. OS를 공부한 이라면, interrupt때 배운 mouse와 keyboard 관련 interrupt를 떠올리면 된다.
위의 종류들의 차이는 비동기적 처리이냐 동기적으로 처리되느냐의 차이가 있다. 이는 Signal and slots가 동기적 처리만 가능한 것과 다른 Event Handling의 특징이다. 비동기적 처리의 장점은 처리에 일종의 최적화가 이루어질 수 있다는 점이다. 특정 widget의 update가 여러차례 연속으로 호출될 경우, 비동기처리에선 다시 그려져야할 영역의 합집합을 대상으로 하는 한번의 update로 합쳐지는 방식의 최적화가 가능하다. (이같은 Event들을 Compressible event라고 부르며, paint event나 move event등이 있음)
event loop는 application이 수행될 때 필수적으로 이루어지는 QApplication
instance의 exec()
호출에서 시작되어 백그라운드로 반복수행이 되고 있으면서 queue에 push된 event들을 다음과 같은 pseudo code와 같은 방식으로 pop하여 event를 처리한다.
while ( !exit ) {
...
while ( !posted_event_queue_is_empty) { // Posted Event
process_next_posted_event();
}
while ( !spontaneous_event_queue_is_empty) { // Spontaneous Event
process_next_spontaneous_event();
}
while ( !posted_event_qeueu_is_empty) { // Posted Event
process_next_posted_event();
}
...
}
Event Handling의 필요성.
signals and slots에 비해 low level programming이라고 할 수 있다. 때문에 custom widget등을 개발하는 경우와 같이 PyQt로 재사용가능한 widget을 만드는 경우 등을 위해서는 event handling을 이용해야한다. 하지만, PyQt는 결국 Qt의 바인딩인터라, 제대로 사용하기 위해서는 Qt의 C++ 라이브러리에 대한 이해 등이 필요하다. 단순히 전형적인 GUI Application를 만드는 경우라면 signals and slots 만으로도 충분해보인다.
Referneces
'Programming' 카테고리의 다른 글
[Basic] Literal (0) | 2023.02.20 |
---|---|
[Programming] Primitive Data Type : C, C++, NumPy, Torch (0) | 2023.02.01 |
[Programming] Library vs. Framework (0) | 2023.01.18 |
[PyQt6] Install PyQt6 on Windows (2) | 2023.01.03 |
[CE] Introduction of WSL (0) | 2022.12.22 |