Qt 安装事件过滤器installEventFilter

(2013-01-28 14:29:18)

  分类: 工作笔记

Qt的事件模型一个强大的功能是一个QObject对象能够监视发送其他QObject对象的事件,在事件到达之前对其进行处理。

假设我们有一个CustomerInfoDialog控件,由一些QLineEdit控件组成。我们希望使用Space键得到下一个QLineEdit的输入焦点。一个最直接的方法是继承QLineEdit重写keyPressEvent()函数,当点击了Space键时,调用focusNextChild():

void MyLineEdit::keyPressEvent(QKeyEvent *event)

{

if (event->key() == Qt::Key_Space) {

focusNextChild();

} else {

QLineEdit::keyPressEvent(event);

}

}

这个方法有一个最大的缺点:如果我们在窗体中使用了很多不同类型的控件(QComboBox,QSpinBox等等),我们也要继承这些控件,重写它们的keyPressEvent()。一个更好的解决方法是让CustomerInfoDialog监视其子控件的键盘事件,在监视代码处实现以上功能。这就是事件过滤的方法。实现一个事件过滤包括两个步骤:

1.      在目标对象上调用installEventFilter(),注册监视对象。

2.      在监视对象的eventFilter()函数中处理目标对象的事件。

注册监视对象的位置是在CustomerInfoDialog的构造函数中:

CustomerInfoDialog::CustomerInfoDialog(QWidget *parent)

: QDialog(parent)

{

...

firstNameEdit->installEventFilter(this);

lastNameEdit->installEventFilter(this);

cityEdit->installEventFilter(this);

phoneNumberEdit->installEventFilter(this);

}

事件过滤器注册后,发送到firstNameEdit,lastNameEdit,cityEdit,phoneNumberEdit控件的事件首先到达CustomerInfoDialog::eventFilter()函数,然后在到达最终的目的地。

下面是eventFilter()函数的代码:

bool CustomerInfoDialog::eventFilter(QObject *target, QEvent *event)

{

if (target == firstNameEdit || target == lastNameEdit

|| target == cityEdit || target == phoneNumberEdit) {

if (event->type() == QEvent::KeyPress) {

QKeyEvent *keyEvent = static_cast(event);

if (keyEvent->key() == Qt::Key_Space) {

focusNextChild();

return true;

}

}

}

return QDialog::eventFilter(target, event);

}

首先,我们看是目标控件是否为QLineEdit,如果事件为键盘事件,把QEvent转换为QKeyEvent,确定被敲击的键。如果为Space键,调用focusNextChild(),把焦点交给下一个控件,返回true通知Qt已经处理了这个事件,如果返回false,Qt将会把事件传递给目标控件,把一个空格字符插入到QLineEdit中。

如果目标控件不是QLineEdit,或者事件不是Space敲击事件,把控制权交给基类QDialog的eventFilter()。目标控件也可以是基类QDialog正在监视的控件。(在Qt4.1中,QDialog没有监视的控件,但是Qt的其他控件类,如QScrollArea,监视一些它们的子控件)

Qt的事件处理有5中级别:

1.      重写控件的事件处理函数:如重写keyPressEvent(),mousePressEvent()和paintEvent(),这是最常用的事件处理方法,我们已经看到过很多这样的例子了。

2.      重写QObject::event(),在事件到达事件处理函数时处理它。在需要改变Tab键的惯用法时这样做。也可以处理那些没有特定事件处理函数的比较少见的事件类型(例如,QEvent::HoverEnter)。我们重写event()时,必须要调用基类的event(),由基类处理我们不需要处理的那些情况。

3.      给QObject对象安装事件过滤器:对象用installEventFilter()后,所有达到目标控件的事件都首先到达监视对象的eventFilter()函数。如果一个对象有多个事件过滤器,过滤器按顺序激活,先到达最近安装的监视对象,最后到达最先安装的监视对象。

4.      给QApplication安装事件过滤器,如果qApp(唯一的QApplication对象)安装了事件过滤器,程序中所有对象的事件都要送到eventFilter()函数中。这个方法在调试的时候非常有用,在处理非活动状态控件的鼠标事件时这个方法也很常用。

5.      继承QApplication,重写notify()。Qt调用QApplication::nofity()来发送事件。重写这个函数是在其他事件过滤器处理事件前得到所有事件的唯一方法。通常事件过滤器是最有用的,因为在同一时间,可以有任意数量的事件过滤器,但是notify()函数只有一个。

许多事件类型,包括鼠标,键盘事件,是能够传播的。如果事件在到达目标对象的途中或者由目标对象处理掉,事件处理的过程会重新开始,不同的是这时的目标对象是原目标对象的父控件。这样从父控件再到父控件,知道有控件处理这个事件或者到达了最顶级的那个控件。

图7.2显示了一个键盘事件在一个对话框中从子控件到父控件的传播过程。当用户敲击一个键盘,时间首先发送到有焦点的控件上(这个例子中是QCheckBox)。如果QCheckBox没有处理这个事件,Qt把事件发送到QGroupBox中,如果仍然没有处理,则最后发送到QDialog中。

转自:http://blog.csdn.net/iamdbl/article/details/1630043#

Qt 安装事件过滤器installEventFilter的更多相关文章

  1. [QT]给QApplication安装事件过滤器 app.installEventFilter

    Qt的事件处理有5种级别: 1.      重写控件的事件处理函数:如重写keyPressEvent(),mousePressEvent()和paintEvent(),这是最常用的事件处理方法,我们已 ...

  2. 关于QT安装的一些心得(QT551, VS2013)项目开发配置,以及项目结构分析

    推荐QT开发的配置如下: 我的硬件配饰中等,所以推荐一下配置: QT551版本,目前QT最新版8.0,为了稳定选择551版本 VS2013IDE, 因为VS2010与VS2013的编译器相同,但是VS ...

  3. QT安装后再添加或删除组件

    QT安装目录下打开MaintenanerceTool.exe 手动添加​储存库,要定位一个储存有QT在线安装镜像的网址: https://download.qt.io/online/qtsdkrepo ...

  4. QT安装在VS2008中的方法

    (一)工欲善其事,必先利其器,废话不多讲. 原文:http://www.cnblogs.com/zwq194/archive/2011/02/19/1958713.html 总结起来网上流行的VS20 ...

  5. 【Win10+eclipse+MinGW+QT安装教程】已有eclipse环境下配置QT插件出错详解

    (纪念一下装了一整天濒临绝望的自己[/doge]) (以下所有下载项一律使用32位) step1:下载安装eclipse.适配的jdk.MinGW和QT 1.下载32位eclipse for c++以 ...

  6. TX1/TX2 Qt安装与配置

    安装Qt 安装Qt Creator,打开终端执行如下命令: sudo apt-get install qt5-default qtcreator -y 安装Qt示例和文档: sudo apt-get ...

  7. Qt安装与配置

    安装Qt 安装Qt Creator,打开终端执行如下命令: sudo apt-get install qt5-default qtcreator -y 安装Qt示例和文档: sudo apt-get ...

  8. Qt 安装与配置记录

    一 安装的时候得选一个Qt安装啊!!不要忘了展开这一项,而只安装Qt creator 展开之后会发现有很多版本,为了方便,选自带编译器mingw,就不需要麻烦的配置了 二 打开Qt creator 后 ...

  9. qmake.exe是在Qt安装编译时生成的,里面内嵌了Qt相关的一些路径(最简单的方法是保持一样的安装路径,最方便的办法是设置qt.conf文件)

    在网上直接下载别人编译好的Qt库,为自己使用省了不少事.但往往也会遇到些问题,其中Qt version is not properly installed,please run make instal ...

随机推荐

  1. vs报错找不到错在哪里!Validation failed for one or more entities

    今天在处理Entity Framework修改数据库时,报错: Validation failed for one or more entities. See 'EntityValidationErr ...

  2. UESTC 485 Game(康托,BFS)

    Today I want to introduce an interesting game to you. Like eight puzzle, it is a square board with 9 ...

  3. C# Static修饰符的作用

    MSDN上的定义 Use the static modifier to declare a static member, which belongs to the type itself rather ...

  4. Quality of service

    w https://en.wikipedia.org/wiki/Quality_of_service Quality of service (QoS) is the overall performan ...

  5. Vue中获取dom元素

    Vue.js虽然说是数据驱动页面的,但是有时候我们也要获取dom对象进行一些操作. vue的不同版本获取dom对象的方法不一样 Vue.js  1.0版本中,通过v-el绑定,然后通过this.els ...

  6. MDF损坏或LDF文件损坏

    MDF损坏或LDF损坏 MDF丢失或LDF丢失 注意,这些情况必须要相同版本的sql server才能操作成功 当MDF损坏时 1.备份结尾日志 http://www.cnblogs.com/gere ...

  7. 解决github访问慢和clone慢解决方案

    在http://tool.chinaz.com/dns/ 这个网站输入github.com 打开cmd ping各个服务器ip地址,看看哪个比较好 windows下C:\Windows\System3 ...

  8. Percona备份mysql全库及指定数据库(完整备份与增量备份)

    Percona Xtrabackup备份mysql全库及指定数据库(完整备份与增量备份) Xtrabackup简介 Percona XtraBackup是开源免费的MySQL数据库热备份软件,它能对I ...

  9. ACM解题之(ZOJ 2724)Windows Message Queue

    题目来源: 点击打开链接 题目翻译: 消息队列是windows系统的基本基础.对于每个进程,系统都维护一个消息队列.如果这个过程发生某些事情,例如鼠标点击,文本改变,系统会向队列添加一条消息.同时,如 ...

  10. python基础知识——包

    包是一种通过使用“模块名”来组织python模块的名称空间的方式. 无论是import形式还是from...import形式,凡是在导入语句中(不是在使用时)遇到带点的,就需要意识到——这是包. 包是 ...