Qt 事件过滤器
Qt创建了QEvent事件对象之后,会调用QObject的event()函数做事件的分发。有时候,你可能需要在调用event()函数之前做一些另外的操作,比如,对话框上某些组件可能并不需要响应回车按下的事件,此时,你就需要重新定义组件的event()函数。如果组件很多,就需要重写很多次event()函数,这显然没有效率。为此,你可以使用一个事件过滤器,来判断是否需要调用event()函数。
QOjbect有一个eventFilter()函数,用于建立事件过滤器。这个函数的签名如下:
virtual bool QObject::eventFilter ( QObject * watched, QEvent * event )如果watched对象安装了事件过滤器,这个函数会被调用并进行事件过滤,然后才轮到组件进行事件处理。在重写这个函数时,如果你需要过滤掉某个事件,例如停止对这个事件的响应,需要返回true。
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == textEdit) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
qDebug() << "Ate key press" << keyEvent->key();
return true;
} else {
return false;
}
} else {
// pass the event on to the parent class
return QMainWindow::eventFilter(obj, event);
}
}上面的例子中为MainWindow建立了一个事件过滤器。为了过滤某个组件上的事件,首先需要判断这个对象是哪个组件,然后判断这个事件的类型。例如,我不想让textEdit组件处理键盘事件,于是就首先找到这个组件,如果这个事件是键盘事件,则直接返回true,也就是过滤掉了这个事件,其他事件还是要继续处理,所以返回false。对于其他组件,我们并不保证是不是还有过滤器,于是最保险的办法是调用父类的函数。
在创建了过滤器之后,下面要做的是安装这个过滤器。安装过滤器需要调用installEventFilter()函数。这个函数的签名如下:
void QObject::installEventFilter ( QObject * filterObj )这个函数是QObject的一个函数,因此可以安装到任何QObject的子类,并不仅仅是UI组件。这个函数接收一个QObject对象,调用了这个函数安装事件过滤器的组件会调用filterObj定义的eventFilter()函数。例如,textField.installEventFilter(obj),则如果有事件发送到textField组件是,会先调用obj->eventFilter()函数,然后才会调用textField.event()。
当然,你也可以把事件过滤器安装到QApplication上面,这样就可以过滤所有的事件,已获得更大的控制权。不过,这样做的后果就是会降低事件分发的效率。
如果一个组件安装了多个过滤器,则最后一个安装的会最先调用,类似于堆栈的行为。
注意,如果你在事件过滤器中delete了某个接收组件,务必将返回值设为true。否则,Qt还是会将事件分发给这个接收组件,从而导致程序崩溃。
事件过滤器和被安装的组件必须在同一线程,否则,过滤器不起作用。另外,如果在install之后,这两个组件到了不同的线程,那么,只有等到二者重新回到同一线程的时候过滤器才会有效。
事件的调用最终都会调用QCoreApplication的notify()函数,因此,最大的控制权实际上是重写QCoreApplication的notify()函数。由此可以看出,Qt的事件处理实际上是分层五个层次:重定义事件处理函数,重定义event()函数,为单个组件安装事件过滤器,为QApplication安装事件过滤器,重定义QCoreApplication的notify()函数。这几个层次的控制权是逐层增大的。
转自:http://devbean.blog.51cto.com/448512/231861
延伸:http://blog.csdn.net/michealtx/article/details/6865891 Qt事件处理的五个层次
Qt 事件过滤器的更多相关文章
- QT事件过滤器(QT事件处理的5个层次:自己覆盖或过滤,父窗口过滤,Application过滤与通知)
Qt事件模型一个真正强大的特色是一个QObject 的实例能够管理另一个QObject 实例的事件. 让我们试着设想已经有了一个CustomerInfoDialog的小部件.CustomerInfoD ...
- Qt事件过滤器和事件的发送
事件过滤器 /* *事件过滤器不是类,仅仅是QObject类的两个函数:installEventFilter() 和 eventFilter() . *下面讲个例子: * 监视过滤 textEdit的 ...
- qt事件过滤器的使用(可以用于控制屏幕背光等)
在嵌入式qt项目中,有时并不需求屏幕一直亮着,需要一段时间不操作时,将屏幕背光关掉,以达到节能的目的: 在qt项目中,可以通过重写事件过滤器来实现屏幕操作的检测,加上定时器的时间控制,可以实现指定时间 ...
- Qt事件过滤器Event Filter
事件过滤器针对一类或者多种不同类型的对象,定义了重写操作. 简单的说: 1.先对UI对象注册Event Filter 例如: ui->drawBtn->installEventFil ...
- QT 事件过滤器 eventFilter
在监测的代码里执行需要的行为. 这可以用event Filter来达到. 设置一个event filter有两个步骤: 1. 在目标对象上调用installEventFilter(),将监测对象注册到 ...
- Qt如何在QTabWidget上绘图
Qt绘图事件必须在paintEvent事件下绘图,这样导致我们在向Qt设计师界面上拖拽的控件绘图时,造成了很大的麻烦. 我们不能在拖拽的控件上写paintEvent函数,但是可以自定义一个类,继承某一 ...
- QT5 QSS QML界面美化视频课程系列 QT原理 项目实战 C++1X STL
QT5 QSS QML界面美化视频课程系列 QT原理 项目实战 C++1X STL 课程1 C语言程序设计高级实用速成课程 基础+进阶+自学 课程2 C语言程序设计Windows GDI图形绘 ...
- Qt入门(8)——事件和事件过滤器
在Qt里,一个事件是继承自QEvent的对象.事件通过调用QObject::event(),被发送到继承自 QObject 的对象.事件发送就是一个事件已经产生,由 QEvent正好去表达,且QObj ...
- Qt中事件分发源代码剖析(一共8个步骤,顺序非常清楚:全局的事件过滤器,再传递给目标对象的事件过滤器,最终传递给目标对象)
Qt中事件分发源代码剖析 Qt中事件传递顺序: 在一个应该程序中,会进入一个事件循环,接受系统产生的事件,并且进行分发,这些都是在exec中进行的.下面举例说明: 1)首先看看下面一段示例代码: in ...
随机推荐
- 命名管道FIFO和mkfifo函数
进程间通信必须通过内核提供的通道,而且必须有一种办法在进程中标识内核提供的某个通道,前面讲过的匿名管道是用打开的文件描述符来标识的.如果要互相通信的几个进程没有从公共祖先那里继承文件描述符,它们怎么通 ...
- System V 消息队列 - 复用消息
消息队列中的消息结构可以由我们自由定义,具备较强的灵活性.通过消息结构可以共享一个队列,进行消息复用.通常定义一个类似如下的消息结构: #define MSGMAXDAT 1024 struct my ...
- spring 多线程
http://blog.csdn.net/chszs/article/details/8219189 一.ThreadPoolTaskExecutor ThreadPoolTaskExecutor的配 ...
- MySQL "replace into" 的坑以及insert相关操作
下面我们主要说一下在插入时候的几种情况: 1:insert ignore 2:replace into 3:ON DUPLICATE KEY UPDATE 关于insert ignore: 关于rep ...
- Laravel 事件系统用法总结(监听事件,观察者模式)
看这篇文章先复习一下设计模式 : https://www.cnblogs.com/fps2tao/p/9640338.html 在理解了观察者模式后,我们开始正文 Laravel 的事件提供了一个简单 ...
- cocos2dx 3.3 getParentToNodeTransform bug
cocos2dx 3.3中getParentToNodeTransform实现如下: const Mat4& Node::getParentToNodeTransform() const { ...
- Centos编译Hadoop 2.x 源码
1. 前言 Hadoop-2.4.0的源码目录下有个BUILDING.txt文件,它介绍了如何在Linux和Windows下编译源代码,本文基本是遵照BUILDING.txt指示来操作的,这里再做一下 ...
- 批处理学习笔记12 - 拷贝大文件到特定目录 Copy命令
~z 获取文件容量大小,配合变量使用 copy 拷贝命令, copy 原地址 新地址 ok,下面上代码 @echo off setlocal enabledelayedexpansion for %% ...
- 把UIView转成UIImage,解决模糊失真问题
近期工作中,遇到一个需求,须要把一个UIView对象转成UIImage对象显示.经过网络搜索.找到例如以下答案: ? 1 2 3 4 5 6 7 8 -(UIImage*)convertViewToI ...
- angular学习笔记(十一)-表达式
本篇只要介绍angular表达式: 在之前的例子中,我们多半是直接把数据作为angular标识符的值,但其实可以使用表达式来做更多的事情: 比如: {{number}} 也可以是: {{number+ ...