QDialog之遮蔽Esc鍵(簡單深刻,要麼重寫keyPressEvent然後break忽略此事件,要麼重寫eventFilter然後return,都是為了忽略此事件)
阿新 • • 發佈:2019-01-25
原始碼分析
通過檢視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鍵的預設動作,則可以通過兩種途徑:
·重寫Esc鍵對應的事件
·重寫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(); }
關於事件過濾器和事件重寫其實是屬於一種情況,都是基於事件判斷和過濾的,而事件過濾器相對來說更易用、擴充套件性更好,不需要針對每個控制元件都去重寫對應的事件。