Qt5相對於Qt4 增長對事件accept()和ignore()函數。web
Qt 中有不少種事件:鼠標事件、鍵盤事件、大小改變的事件、位置移動的事件等等。對於事件的處理,咱們Qt 中使用相對應的機制。
event()函數
1. event()函數是一個 protected 的函數,這意味着咱們要想重寫event(),必須繼承一個已有的類。
2. 各個組件對事件處理是併發修改,仍是挨個修改呢?併發
bool Test::event(QEvent *e) { if (e->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(e); if (keyEvent->key() == Qt::Key_Tab) { qDebug() << "You press tab."; return true; } } return QWidget::event(e); }
eventFilter()函數
app
virtual bool QObject::eventFilter ( QObject * watched, QEvent * event );
bool Test::eventFilter(QObject *object, QEvent *event) { if (object == target && event->type() == QEvent::KeyPress) { QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event); if (keyEvent->key() == Qt::Key_Tab) { qDebug() << "You press tab."; return true; } else { return false; } } return false; }
總結Qt 的事件處理
1. 重寫paintEvent()、mousePressEvent()等事件處理函數。這是最普通、最簡單的形式,同時功能也最簡單。
2. 重寫event()函數。event()函數是全部對象的事件入口,QObject和QWidget中的實現,默認是把事件傳遞給特定的事件處理函數。
3. 在特定對象上面安裝事件過濾器。該過濾器僅過濾該對象接收到的事件。
4. 在QCoreApplication::instance()上面安裝事件過濾器。該過濾器將過濾全部對象的全部事件,所以和notify()函數同樣強大,可是它更靈活,由於能夠安裝多個過濾器。全局的事件過濾器能夠看到 disabled 組件上面發出的鼠標事件。全局過濾器有一個問題:只能用在主線程。(受線程影響)
5. 重寫QCoreApplication::notify()函數。這是最強大的,和全局事件過濾器同樣提供徹底控制,而且不受線程的限制。可是全局範圍內只能有一個被使用(由於QCoreApplication是單例的)。函數
class Label : public QWidget { public: Label() { installEventFilter(this); } bool eventFilter(QObject *watched, QEvent *event) { if (watched == this) { if (event->type() == QEvent::MouseButtonPress) { qDebug() << "eventFilter"; } } return false; } protected: void mousePressEvent(QMouseEvent *) { qDebug() << "mousePressEvent"; } bool event(QEvent *e) { if (e->type() == QEvent::MouseButtonPress) { qDebug() << "event"; } return QWidget::event(e); } }; class EventFilter : public QObject { public: EventFilter(QObject *watched, QObject *parent = 0) : QObject(parent), m_watched(watched) { } bool eventFilter(QObject *watched, QEvent *event) { if (watched == m_watched) { if (event->type() == QEvent::MouseButtonPress) { qDebug() << "QApplication::eventFilter"; } } return false; } private: QObject *m_watched; }; int main(int argc, char *argv[]) { QApplication app(argc, argv); Label label; app.installEventFilter(new EventFilter(&label, &label)); label.show(); return app.exec(); }
輸出結果是:post
QApplication::eventFilter eventFilter event mousePressEvent
所以能夠知道,全局事件過濾器被第一個調用,以後是該對象上面的事件過濾器,其次是event()
函數,最後是特定的事件處理函數。this
registerEventType()函數 ------- 用於自定義事件的註冊spa
static int QEvent::registerEventType ( int hint = -1 );
發送方式:.net
static bool QCoreApplication::sendEvent(QObject *receiver,QEvent *event);
例子:線程
QMouseEvent event(QEvent::MouseButtonPress, pos, 0, 0, 0); QApplication::sendEvent(mainWindow, &event); static void QCoreApplication::postEvent(QObject *receiver,QEvent *event);
注意:在事件被髮送的時候,event對象並不會被銷燬。一般咱們會在棧上建立event對象code
參考資料:
http://www.devbean.net/2012/10/qt-study-road-2-event-summary/