簡述
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鍵的默認動作,則可以通過兩種途徑:
-
重寫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();
}
關於事件過濾器和事件重寫其實是屬於一種情況,都是基於事件判斷和過濾的,而事件過濾器相對來說更易用、擴展性更好,不需要針對每個控件都去重寫對應的事件。
更多參考:
原文作者:一去丶二三里
作者博客:去作者博客空間