今天要說的是event()函數。記得之前曾經提到過這個函數,說在事件對象創建完畢後,Qt將這個事件對象傳遞給QObject的event()函數。 event()函數並不直接處理事件,而是將這些事件對象按照它們不同的類型,分發給不同的事件處理器(event handler)。
event() 函數主要用於事件的分發,所以,如果你希望在事件分發之前做一些操作,那麼,就需要注意這個event()函數了。為了達到這種目的,我們可以重寫 event()函數。例如,如果你希望在窗口中的tab鍵按下時將焦點移動到下一組件,而不是讓具有焦點的組件處理,那麼你就可以繼承QWidget,並重寫它的event()函數,已達到這個目的:
bool MyWidget::event(QEvent *event) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Tab) {
// 處理Tab鍵
return true;
}
}
return QWidget::event(event);
}
event() 函數接受一個QEvent對象,也就是需要這個函數進行轉發的對象。為了進行轉發,必定需要有一系列的類型判斷,這就可以調用QEvent的type() 函數,其返回值是QEvent::Type類型的枚舉。我們處理過自己需要的事件後,可以直接return回去,對於其他我們不關心的事件,需要調用父類的event()函數繼續轉發,否則這個組件就只能處理我們定義的事件了。
event()函數返回值是bool類型,如果傳入的事件已被識別並且處理,返回true,否則返回false。如果返回值是true,QApplication會認為這個事件已經處理完畢,會繼續處理事件隊列中的下一事件;如果返回值是false,QApplication會嘗試尋找這個事件的下一個處理函數。
event()函數的返回值和事件的 accept()和ignore()函數不同。accept()和ignore()函數用於不同的事件處理器之間的溝通,例如判斷這一事件是否處理;event()函數的返回值主要是通知QApplication的notify()函數是否處理下一事件。為了更加明晰這一點,我們來看看 QWidget的event()函數是如何定義的:
bool QWidget::event(QEvent *event) {
switch (e->type()) {
case QEvent::KeyPress:
keyPressEvent((QKeyEvent *)event);
if (!((QKeyEvent *)event)->isAccepted())
return false;
break;
case QEvent::KeyRelease:
keyReleaseEvent((QKeyEvent *)event);
if (!((QKeyEvent *)event)->isAccepted())
return false;
break;
// more...
}
return true;
}
QWidget 的event()函數使用一個巨大的switch來判斷QEvent的type,並且分發給不同的事件處理函數。在事件處理函數之後,使用這個事件的 isAccepted()方法,獲知這個事件是不是被接受,如果沒有被接受則event()函數立即返回false,否則返回true。
另外一個必須重寫event()函數的情形是有自定義事件的時候。如果你的程序中有自定義事件,則必須重寫event()函數以便將自定義事件進行分發,否則你的自定義事件永遠也不會被調用。關於自定義事件,我們會在以後的章節中介紹。
出處:http://devbean.blog.51cto.com/448512/230883