Qt學習之路(21): event()

今天要說的是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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章