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 ...
随机推荐
- selenium 并发执行测试用例
转帖: 要想多线程并发的运行WebDriver,必须同时满足2个条件,首先你的测试程序是多线程,其次需要用到Selenium Server(selenium-server-standalone-XXX ...
- Smarty中section的使用
在smarty的使用过程中,有很多时候需要将一个数组输出到模板中来处理,以下将演示如何将一个索引(index)数组和关联(assocaite)数组在页面中展现出来. 本文中假设有如下一个索引数组 1 ...
- sqlserver中将varchar类型转换为int型再进行排序的方法
sql中把varchar类型转换为int型然后进行排序,如果我们数据库的ID设置为varchar型的 在查询的时候order by id的话 如果我们数据库的ID设置为varchar型的 在查询的时候 ...
- scrapy 的一个例子
1.目标: scrapy 是一个爬虫构架,现用一个简单的例子来讲解,scrapy 的使用步骤 2.创建一个scrapy的项目: 创建一个叫firstSpider的项目,命令如下: scrapy sta ...
- Spring中的内部Bean
简介 当一个bean仅被用作另一个bean的属性时,它能被声明为一个内部bean,为了定义inner bean,在Spring 的 基于XML的 配置元数据中,可以在 <property/> ...
- [tools]python的mkdocs模块分分钟将md搞成一个网站
docusaurus: facebook出的一个文档生成器,用起来感觉没那么友善 hugo: 这个很棒 python的mkdocs模块: 用起来最简单 python的这个模块可以分分钟将一坨md假设成 ...
- 【Android】3.19 示例19--全景图HelloWorld
分类:C#.Android.VS2015.百度地图应用: 创建日期:2016-02-04 百度全景图是一种实景地图服务.为用户提供城市.街道和其他环境的360度全景图像,用户可以通过该服务获得如临其境 ...
- iOS: 让键盘消失的的4种方法
转自:http://leopard168.blog.163.com/blog/static/168471844201422121310352/ 在iOS app中,只要用到编辑框(UITextFiel ...
- mysql 下载
mysql 下载
- Shell执行将脚本里的变量打印到指定日志文件
首先需要定位获取任务的运行日志或者报错信息,才能定位问题. 通过shell调用有些脚本的话,日志信息会打印在shell里.不过也有用户在shell里调用正常,但是到crontab调用的时候就出错并且没 ...