Qt Event Dispatcher學習
距離上次整理Qt事件系統已經過了14個月了。重新理理思緒:
Qt中的事件大致可分為3類:
Spontaneous events |
從系統得到的訊息:滑鼠按鍵、鍵盤按鍵、定時器事件等。轉化為QEvent後被Qt事件系統依次處理 |
Posted events |
由Qt或應用程式直接生成,放入Qt訊息佇列 |
Sent events |
由Qt或應用程式產生,不放入佇列直接被派發和處理 |
本文中,先簡單看一下後兩種,然後重點看看第一種。
Sent events
比如,傳送按鍵"X"的事件到 mainWin 視窗。
QKeyEvent event(QEvent::KeyPress, Qt::Key_X, Qt::NoModifier, "X", 0 ); QApplication::sendEvent(mainWin, &event);
如果沒有過濾器的話,這其實就是直接呼叫 mainWin 的 keyPressEvent()函式。
這個東西不涉及事件佇列、事件迴圈等等東西。但是事件過濾在這個過程中正常起作用。而且除過濾器外,下面三個函式在派生類中都可以被覆蓋(以處理這個事件):
- QApplication::notify()
- QWidget::event()
- QWidget::keyPressEvent()
Posted events
比如,同樣是傳送按鍵"X"的事件到 mainWin 視窗,我們可以使用postEvent()。
QApplication::postEvent(mainWin, new QKeyEvent(QEvent::KeyPress, Qt::Key_X, Qt::NoModifier, "X", 0 ));
這會將該事件放入Qt自己的事件佇列中,事件迴圈QEventLoop空閒時會判斷該佇列是否為空。最終使用 sendEvent() 依次派發事件佇列中的這些事件。
也可以手動使用
- QCoreApplication::sendPostedEvents()
清空當前執行緒事件佇列(即派發佇列中的事件)
注意:每一個執行緒有一個事件佇列。
Spontaneous events
系統底層事件是通過 QAbstractEventDispatcher 整合進Qt的事件迴圈的。
Event dispatcher接受視窗系統以及其他源中的事件。它對事件的傳遞提供了一種精細控制的能力。
QAbstractEventDispatcher
- QEventDispatcherUNIX
- QEventDispatcherX11
- QEventDispatcherQWS
- QEventDispatcherQPA
- QEventDispatcherGlib
- QGuiEventDispatcherGlib
- QWSEventDispatcherGlib
- QEventDispatcherWin32
- QGuiEventDispatcherWin32
- QEventDispatcherMac
- ...
這堆東西還挺多,不過下面三個屬於QtCore模組
QEventDispatcherGlib |
使用glib事件迴圈,有助於和Gtk的整合 |
QEventDispatcherUNIX |
預設的glib不可用時,就用這個嘍 |
QEventDispatcherWin32 |
Qt 建立一個帶回調函式的隱藏視窗來處理事件。 |
我們能看的到的就是,它們提供
- Timer
-
SockerNotifer
的註冊、反註冊功能。並將系統底層對應事件轉換成Qt事件。
其他的屬於QtGui模組。就是和視窗系統(重繪、移動等等事件)以及鍵鼠事件有關了。