- Event Accept or Ignore and event() method
void CustomLabel::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) { // 指定處理當滑鼠左鍵按下事件 // .... } else { // 由父類別所定義的事件處理函式來處理 QLabel::mousePressEvent(event); } } void CustomLabel::mouseReleaseEvent(QMouseEvent *event) { // 滑鼠放開事件處理.... }
每個可傳播的事件都有accept()與igore()兩個方法,用以告知Qt應用程式,這個事件處理者是否接受或忽略此一事件,如果事件處理者中呼叫事件的accept(),則事件不會再進一步傳播,若呼叫了ignore(),則Qt應用程式會嘗試尋找另一個事件的接受者,您可以藉由isAccepted()方法得知事件是否被接受。
一般來說,除了QCloseEvent之外,很少直接呼叫accept()或ignore(),如果您接受事件,則在事件處理者當中實作對事件的處理(如上例的if陳述句),如果您不接受事件,則直接呼叫父類別的事件實作(如上例的else陳述句),對於QWidget來說,預設的實作如下,由於QWidget預設的實作是呼叫ignore(),這讓事件可以向父元件傳播。
void QWidget::keyPressEvent(QKeyEvent *event) { event->ignore(); }
- QCloseEvent則建議直接呼叫accept()與ignore(),accept()方法會繼續關閉的操作,ignore()則會取消關閉的操作:
void MainWindow::closeEvent(QCloseEvent *event) { if (continueToClose()) { event->accept(); } else { event->ignore(); } }
QObject的event()方法通常用於分派事件,但在某些情況下,您希望在事件分派給其它事件處理者之前,先行作一些處理,則可以重新定義event()方法,例如在視窗程式中,Tab鍵按下時希望其將焦點移至下一個圖型元件,而不是直接讓目前焦點的圖形元件直接處理Tab鍵,則您可以在繼承QWidget子類別時,重新定義其event()方法,例如:
bool CustomWidget::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); }Notes:
- 在執行時期想要知道所取得之QEvent類型,可以使用QEvent的type()方法取得常數值,並與QEvent::Type作比對。
- 對event作強制形態轉換為QKeyEvent並宣告為keyEvent,新的keyEvent可以使用QKeyEvent的成員。
if (event->type() == QEvent::KeyPress)
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
事件若順利處理完畢,則要傳回true,表示這個事件被接受並處理,QApplication可以繼續事件佇列中的下一個事件處理,若傳回false,則QApplication嘗試尋找下一個可以處理事件的方法。不用透過呼叫事件的accept()或ignore(),這也沒有意義,accept()或ignore()是用來在特定的事件處理者之間作溝通,而event()的true或false,是用來告知QApplication的notify()方法是否處理下一事件,以QWidget的event()實作來說,它是根據事件的isAccepted()來判斷該傳回true或false。
bool QWidget::event(QEvent *event) { switch (event->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; ... } return true; }
- 當重新定義event()的情況是自訂CustomEvent子類型時,可以將之分派給其它函式或直接在event()中處理,自訂事件必須是CustomEvent的子類別,也可以直接實作customEvent()方法來處理自訂事件,例如:
bool CustomWidget::event(QEvent *event) { if (event->type() == MyCustomEventType) { CustomEvent *myEvent = static_cast<CustomEvent *>(event); // 對自訂事件的處理,或呼叫其它函式來處理事件 return true; } return QWidget::event(event); }
本文參考自"良葛格:Qt4學習筆記"
0 意見:
張貼留言