下面是自己測試代碼,有瑕疵但是可以實現
[cpp]
.h
MainWindow(QObject *target);
bool eventFilter(QObject *target,QEvent *event);
.main.cpp
傳入APP
int main(int argc, char *argv[]){ QApplication app(argc, argv); MainWindow mainWin(&app); mainWin.show(); return app.exec();}.cpp
安裝事件過濾器
MainWindow::MainWindow(QObject *target)
{
target->installEventFilter(this);
}
//改寫
bool MainWindow::eventFilter(QObject *target,QEvent *event)
{
//if(target == spreadsheet)
{
if(event->type() == QEvent::KeyPress)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if(keyEvent->key() == Qt::Key_A)
{
QKeyEvent event(QEvent::KeyPress,Qt::Key_B,Qt::NoModifier,"B", 0);
QApplication::sendEvent(target,&event);
return true;
}
}
}
return QWidget::eventFilter(target, event);
}
Qt中的事件大致可分為3類:
Spontaneous events
從系統得到的消息:鼠標按鍵、鍵盤按鍵、定時器事件等。轉化為QEvent後被Qt事件系統依次處理
Posted events
由Qt或應用程序直接生成,放入Qt消息隊列
QCoreApplication::postEvent()
Sent events
由Qt或應用程序產生,不放入隊列直接被派發和處理
QCoreApplication::sendEvent()
本文中,先簡單看一下後兩種,然後重點看看第一種。
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模塊。就是和窗口系統(重繪、移動等等事件)以及鍵鼠事件有關了。
作者:jingzhesiye