有關Qt事件的接收與忽略的一些理解

有些時候,我們需要在自己的類中重寫 XXXEvent() 這個虛函數,就像下面這樣:

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
protected:
    virtual void mousePressEvent(QMouseEvent*);
};

以mousePressEvent()鼠標點擊函數爲例,我們的需求是這樣的:如果是鼠標左鍵點擊,那麼做相關處理;如果是右鍵,則什麼都不做。那麼函數應該這麼寫:

void MainWindow::mousePressEvent(QMouseEvent* e)
{
    //Qt事件類中的accepted值默認是true的,也就是說如果我們想接收某個事件,不用調用accept(),除非說之前調用了ignore()
    if(e->button() == Qt::LeftButton)
    {
        //接受這個事件,並做一些處理...
    }
    else
    {
        //默認是調用父類的mousePressEvent(),既然我們不想處理,那就按照默認的方法好了
        QWidget::mousePressEvent(e);
    }
}
一般來說,父類QWidget裏的XXXEvent()函數內容大多是忽略這個事件( 即e->ignore() ) ,然後可能會有一些額外的操作什麼的,結束後然後再傳到父組件那裏。如果你直接用e->ignore()的話,那就相當於沒有做父類XXXEvent()裏面的額外的操作而直接傳到父組件那裏了,這樣有可能會帶來一些問題。
所以大多數時候,如果你自己的XXXEvent()函數裏不想處理,那就調用父類的相應函數來做默認的處理,這樣比較保險。

但有些時候比較特殊,比如closeEvent()。當我們點擊關閉按鈕時,QWidget::close()函數會發出一個QCloseEvent事件,然後最終如果這個事件被接收了的話,則關閉窗口,否則就什麼都不做。

而QWidget::closeEvent()裏是調用e->accept(),即默認是關閉窗口,而event類的accepted值又是默認爲true的,所以如果我們不想關閉窗口,就必須調用e->ignore(),像這樣:

void MainWindow::closeEvent(QCloseEvent* e)
{
    int choose = QMessageBox::warning(this,"warning!","are you sure you want to quit?", QMessageBox::Yes | QMessageBox::No,QMessageBox::No);

    //如果用戶點擊了Yes,那麼窗口就會關閉
    if(choose == QMessageBox::Yes)
        e->accept();
    else
        e->ignore();
}

當然,具體實現時你的XXXEvent()函數可能會採用其他的一些方式,有可能你會先會在自己的XXXEvent()函數裏做一些操作,然後再調用父類的XXXEvent()。有時候你也可以在這個組件的父組件類裏的XXXEvent()裏作一些操作。

Qt事件詳細學習:
Qt學習之路:事件,事件的接收與忽略
Qt中事件處理的方法和實例

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章