简述

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();
}

关于事件过滤器和事件重写其实是属于一种情况,都是基于事件判断和过滤的,而事件过滤器相对来说更易用、扩展性更好,不需要针对每个控件都去重写对应的事件。

更多参考:

QDialog之屏蔽Esc键的更多相关文章

  1. 【Qt】QDialog之屏蔽Esc键【转】

    简述 Qt中Esc键会在一些控件中默认的进行一些事件的触发,比如:QDialog,按下Esc键窗口消失.大多数情况下,我们不需要这么做,那么就需要对默认事件进行屏蔽. 简述 源码分析 事件过滤器 事件 ...

  2. QDialog之屏蔽Esc键(简单深刻,要么重写keyPressEvent然后break忽略此事件,要么重写eventFilter然后return,都是为了忽略此事件)

    简述 Qt中Esc键会在一些控件中默认的进行一些事件的触发,比如:QDialog,按下Esc键窗口消失.大多数情况下,我们不需要这么做,那么就需要对默认事件进行屏蔽. 简述 源码分析 事件过滤器 事件 ...

  3. QDialog之屏蔽Esc键(过滤,或者丢弃)

    http://blog.csdn.net/u011012932/article/details/50357323

  4. MFC非模态对话框中屏蔽ESC键

    个人的编程经验认为:对于非模态对话框,按下ESC键和点击红叉都会响应OnCancel()函数,而不会去响应OnClose()函数. 我们都知道,如果想屏蔽Enter键,只须重写OnOK()函数即可(重 ...

  5. MFC对话框程序 屏蔽ESC和ENTER键关闭对话框的方法

    http://blog.csdn.net/xgx198831/article/details/6713651 MFC对话框程序  屏蔽ESC和ENTER键关闭对话框的方法 或许还有其它更好的办法,但下 ...

  6. MFC对话框中解决回车键、ESC键退出的方法

    BOOL CYourDlg::PreTranslateMessage(MSG* pMsg) { if(pMsg->message==WM_KEYDOWN&&pMsg->wP ...

  7. MFC对话框屏蔽Enter和ESC键

    MFC对话框屏蔽Enter和ESC键参考:http://www.docin.com/p-122354833.html 方法一重载PreTranslateMessage函数 BOOL CXXDlg::P ...

  8. VC MFC 屏蔽ESC和ENTER键关闭对话框

    方法一: 窗体头文件中加入: protected: virtual BOOL PreTranslateMessage(MSG* pMsg); // PreTranslateMessage是消息在送给T ...

  9. qt之esc键

    Esc键对大家来说实在熟悉不过的了,在Qt中Esc键也会默认的进行一些事件的触发,今天对Esc键测试了一下,突然发现不像我想象的那样,在QDialog中按下Esc键会默认调用reject()方法而不是 ...

随机推荐

  1. IE如何兼容placeholder属性

    在前端开发中,经常需要为input设置placeholder属性,但是placeholder是HTML5新属性,在IE10以下不兼容,那么如何完美兼容呢? 网上搜索了一下,其实也挺简单的,可以采用以下 ...

  2. 疯狂java讲义——继承

    本文章只是记录我在学习疯狂java讲义里面,对之前java知识查缺补漏进行的总结. 方法重写 方法重写要遵循"两同两小一大"规则."两同"即方法名相同.形参列表 ...

  3. 几种基于HTTP协议的RPC性能比较

    有了整体的了解后,可以发现Hessian的这个远程过程调用,完全使用动态代理来实现的,其实从客户端代码不难看出,HessianProxyFactory的create方法就是创建接口Basic的代理类, ...

  4. unity资源(移动版)提取 一点尝试

    原地址:http://blog.csdn.net/delguoqing/article/details/22619711 最近在参与一款手游,需要制定美术制作规范.因为拿不准主意,所以决定参考其他游戏 ...

  5. 充分发挥异步在 ASP.NET 中的强大优势

    作者:Brij Bhushan Mishra 最近几年,异步编程受到极大关注,主要是出于两个关键原因:首先,它有助于提供更好的用户体验,因为不会阻塞 UI 线程,避免了处理结束前出现 UI 界面挂起. ...

  6. 40页PPT告诉你真正的"互联网+"

    点这里 40页PPT告诉你真正的"互联网+" 2015-04-06 网站分析公会 超过50万名互联网从业人士关注 互联网运营领域最具影响力自媒体 本文根据和君赵大伟关于互联网思维大 ...

  7. Windows启动系统程序命令

    DEVMGMT.MSC - Device Manager 设备管理器 DISKMGMT.MSC - Disk Management 磁盘管理   WindowsXP常用命令http://baike.b ...

  8. Microsoft SDK 中Sample案例之Amcap項目 的运行方法(转)

    http://blog.csdn.net/erick08/article/details/7194575 Microsoft  SDK 中Sample之Amcap 的运行方法      写这篇文章的由 ...

  9. VISO下载地址

    http://pan.baidu.com/share/home?uk=4011207371#category/type=0

  10. C和C++中结构体(struct)、联合体(union)、枚举(enum)的区别

    C++对C语言的结构.联合.枚举 这3种数据类型进行了扩展. 1.C++定义的结构名.联合名.枚举名 都是 类型名,可以直接用于变量的声明或定义.即在C++中定义变量时不必在结构名.联合名.枚举名 前 ...