简述

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

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

更多参考:


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

【Qt】QDialog之屏蔽Esc键【转】的更多相关文章

  1. 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. qt之esc键

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

  8. Qt编程中QDiaog的ESC键(按下Esc键会默认调用reject()方法)

    最近使用QDialog时,按了下Esc键,导致QDialog被关闭,而后续的数据处理出现了问题.原来在QDialog中按下Esc键会默认调用reject()方法而不是closeEvent(QClose ...

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

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

随机推荐

  1. The Socket API, Part 3: Concurrent Servers

    转:http://www.linuxforu.com/2011/10/socket-api-part-3-concurrent-servers/ By Pankaj Tanwar on October ...

  2. MR中的combiner和partitioner

    1.combiner combiner是MR编程模型中的一个组件: 有些任务中map可能会产生大量的本地输出,combiner的作用就是在map端对输出先做一次合并,以减少map和reduce节点之间 ...

  3. Socket 之 c#实现Socket网络编程

    一.命名空间: 在网络环境下,最有用的两个命名空间是System.Net和 System.Net.Sockets. 1.System.Net:通常与较高程的操作有关,例如download或upload ...

  4. oc语言复制视频文件

    void copyFile() { NSString *home=NSHomeDirectory(); NSString *path=[NSString stringWithFormat:@" ...

  5. Java Script基础(三) 函数

    一.JavaScript中的函数 在JavaScript中,函数类似于Java中的方法,是执行特定功能的代码块,可以重复调用.JavaScript中的函数分为两种,一种是系统函数,另一种是自定义函数. ...

  6. .NET强制进行即时垃圾回收

    大家知道,.NET控制系统垃圾回收(一种自动回收未使用内存的服务)是自动的. 可有时候需要手动强制进行即时垃圾回收. 代码如下: GC.Collect();

  7. JAVA数字证书制作生成

    1.加密算法 为了网络通讯中的报文安全,一般需要对报文进行加密,目前常用的加密算法有: 非对称加密算法:又称公钥加密算法,如RSA.DSA/DSS,最常用的就是RSA算法(算法公开,可自行百度了解算法 ...

  8. Java跳出循环-break和continue语句

    在实际编程中,有时需要在条件语句匹配的时候跳出循环.在Java里,由break和continue语句控制. “break”语句 “break”语句用来结束循环,即不再执行后边的所有循环. 示例:计算1 ...

  9. javaweb学习总结二十四(servlet经常用到的对象)

    一:ServletConfig对象 1:用来封装数据初始化参数,在服务器web.xml配置文件中可以使用<init-param>标签配置初始化参数. 2:实例演示 web.xml文件中配置 ...

  10. centos6.5 iptables实现端口转发

    将本地接口IP 61.144.a.b 的3389端口 转发到 116.6.c.d的3389      (主要访问到61.144.a.b的3389端口,就会跳转到116.6.c.d的3389) [步骤] ...