Qt學習之路(20): 事件接收與忽略

本章內容也是關於Qt事件。或許這一章不能有一個完整的例子,由於對於事件老是感受很抽象,仍是從底層上理解一下比較好的吧!

前面說到了事件的做用,下面來看看咱們如何來接收事件。回憶一下前面的代碼,咱們在子類中重寫了事件函數,以便讓這些子類按照咱們的須要完成某些功能,就像下面的代碼:app

void MyLabel::mousePressEvent(QMouseEvent * event)
{
         if( event->button() == Qt::LeftButton) {
                 // do something
        } else {
                QLabel::mousePressEvent( event);
        }
}


上面的代碼和前面相似,在鼠標按下的事件中檢測,若是按下的是左鍵,作咱們的處理工做,若是不是左鍵,則調用父類的函數。這在某種程度上說,是把事件向上傳遞給父類去響應,也就是說,咱們在子類中「忽略」了這個事件。

咱們能夠把Qt的事件傳遞當作鏈狀:若是子類沒有處理這個事件,就會繼續向其餘類傳遞。其實,Qt的事件對象都有一個accept()函數和ignore()函數。正如它們的名字,前者用來告訴Qt,事件處理函數「接收」了這個事件,不要再傳遞;後者則告訴Qt,事件處理函數「忽略」了這個事件,須要繼續傳遞,尋找另外的接受者。在事件處理函數中,能夠使用isAccepted()來查詢這個事件是否是已經被接收了。

事實上,咱們不多使用accept()和ignore()函數,而是想上面的示例同樣,若是但願忽略事件,只要調用父類的響應函數便可。記得咱們曾經說過,Qt中的事件大部分是protected的,所以,重寫的函數一定存在着其父類中的響應函數,這個方法是可行的。爲何要這麼作呢?由於咱們沒法確認父類中的這個處理函數沒有操做,若是咱們在子類中直接忽略事件,Qt不會再去尋找其餘的接受者,那麼父類的操做也就不能進行,這可能會有潛在的危險。另外咱們查看一下QWidget的mousePressEvent()函數的實現:ide

void QWidget::mousePressEvent(QMouseEvent * event)
{
         event->ignore();
         if ((windowType() == Qt::Popup)) {
                 event->accept();
                QWidget* w;
                 while ((w = qApp->activePopupWidget()) && w != this){
                        w->close();
                         if (qApp->activePopupWidget() == w) // widget does not want to dissappear
                                w->hide(); // hide at least
                }
                 if (!rect().contains( event->pos())){
                        close();
                }
        }
}


請注意第一條語句,若是全部子類都沒有覆蓋mousePressEvent函數,這個事件會在這裏被忽略掉,這暗示着這個組件不關心這個事件,這個事件就可能被傳遞給其父組件。

不過,事情也不是絕對的。在一個情形下,咱們必須使用accept()和ignore()函數,那就是在窗口關閉的時候。若是你在窗口關閉時須要有個詢問對話框,那麼就須要這麼去寫:函數

void MainWindow::closeEvent(QCloseEvent * event)
{
         if(continueToClose()) {
                 event->accept();
        } else {
                 event->ignore();
        }
}

bool MainWindow::continueToClose()
{
         if(QMessageBox::question( this,
                                            tr( "Quit"),
                                            tr( "Are you sure to quit this application?"),
                                            QMessageBox::Yes | QMessageBox::No,
                                            QMessageBox::No)
                == QMessageBox::Yes) {
                 return true;
        } else {
                 return false;
        }
}


這樣,咱們通過詢問以後才能正常退出程序。ui

相關文章
相關標籤/搜索