【Qt】QDialog之屏蔽Esc鍵【轉】


簡述

Qt中Esc鍵會在一些控件中默認的進行一些事件的觸發,比如:QDialog,按下Esc鍵窗口消失。大多數情況下,我們不需要這么做,那么就需要對默認事件進行屏蔽。

源碼分析

通過查看QDialog的源碼,我們很容易會發現keyPressEvent事件中,當按下Esc鍵時,會默認執行reject()。

void QDialog::keyPressEvent(QKeyEvent *e)
{
    // Calls reject() if Escape is pressed. Simulates a button
    // click for the default button if Enter is pressed. Move focus
    // for the arrow keys. Ignore the rest.
#ifdef Q_OS_MAC
    if(e->modifiers() == Qt::ControlModifier && e->key() == Qt::Key_Period) {
        reject();
    } else
#endif
    if (!e->modifiers() || (e->modifiers() & Qt::KeypadModifier && e->key() == Qt::Key_Enter)) {
        switch (e->key()) {
        case Qt::Key_Enter:
        case Qt::Key_Return: {
            QList<QPushButton*> list = findChildren<QPushButton*>();
            for (int i=0; i<list.size(); ++i) {
                QPushButton *pb = list.at(i);
                if (pb->isDefault() && pb->isVisible()) {
                    if (pb->isEnabled())
                        pb->click();
                    return;
                }
            }
        }
        break;
        case Qt::Key_Escape:
            reject();
            break;
        default:
            e->ignore();
            return;
        }
    } else {
        e->ignore();
    }
}

Ok,我們如果想改變Esc鍵的默認動作,則可以通過兩種途徑:

  1. 重寫Esc鍵對應的事件

  2. 重寫reject()

事件過濾器

對QDialog使用事件過濾器,過濾Esc鍵。

installEventFilter(new EventFilter(this));

bool EventFilter::eventFilter(QObject *obj, QEvent *event)
{
    QDialog *pDialog = qobject_cast<QDialog *>(obj);
    if (pDialog != NULL)
    {
        switch (event->type())
        {
        case QEvent::KeyPress:
        {
            QKeyEvent *pKeyEvent = static_cast<QKeyEvent*>(event);
            if (pKeyEvent->key() == Qt::Key_Escape)
            {
                return true;
            }
        }
        }
    }
    return QObject::eventFilter(obj, event);
}

事件重寫

重寫QDialog的鍵盤事件keyPressEvent。

void Dialog::keyPressEvent(QKeyEvent *event)
{
    switch (event->key())
    {
    case Qt::Key_Escape:
        break;
    default:
        QDialog::keyPressEvent(event);
    }
}

重寫reject

m_bClosed為關閉的條件,為true時,窗口才會關閉。

void Dialog::reject()
{
    if (m_bClosed)
        QDialog::reject();
}

關於事件過濾器和事件重寫其實是屬於一種情況,都是基於事件判斷和過濾的,而事件過濾器相對來說更易用、擴展性更好,不需要針對每個控件都去重寫對應的事件。

更多參考:


原文作者:一去丶二三里
作者博客:去作者博客空間


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM