installEventFilter可以安装到任何QObject的子类,并不仅仅是UI组件。事件过滤器和安装过滤器的组件必须在同一线程,在它们分属在不同线程时,事件过滤器也是不起作用的

Qt的事件知识点:
 ①事件对象创建完毕后,Qt 将这个事件对象传递给 QObject 的 event() 函数。event() 函数并不直接处理事件,而是将这些事件对象按照它们不同的类型,分发给不同的事件处理器(event handler)。

②event() 函数主要用于事件的分发。

③事件过滤例子:

解释这个例子之前先看:bool eventFilter(QObject*obj,QEvent*event); [virtual]
注意: eventFilter 函数返回 bool 值,

即, 如果你要自己处理事件, 并且“吞掉”事件,阻止父类对事件的继续处理, 就返回 true; 如果需要父类也处理这一事件,返回 false。通俗点说就是:

它会检查接收到的事件。如果这个事件是我们感兴趣的类型,就进行我们自己的处理;如果不是,就继续转发。

这个函数返回一个 bool 类型,如果你想将参数 event过滤出来,比如,不想让它继续转发,就返回 true,否则返回 false。事件过滤器的调用时间是目标对象(也就是参数里面的 watched对象)接收到事件对象之前。也就是说,如果你在事件过滤器中停止了某个事件,那么,watched对象以及以后所有的事件过滤器根本不会知道这么一个事件。

那么上面的例子的意思就是:

MainWindow是我们定义的一个类,这个类里面会定义许多不同的组件,比如texEdit,我们就是使用MainWindow的eventFilter()函数对它上面的组件进行过滤事件。我们重写了它的 eventFilter()函数。为了过滤特定组件上的事件,首先需要判断这个对象是不是我们感兴趣的组件,然后判断这个事件的类型。在上面的代码中,我们不想让textEdit组件处理键盘按下的事件。所以,首先我们找到这个组件,如果这个事件是键盘事件,则直接返回 true,也就是过滤掉了这个事件,其他事件还是要继续处理,所以返回 false。对于其它的组件,我们并不保证是不是还有过滤器,于是最保险的办法是调用父类的函数。

当返回true是textEdit组件内部是不能用键盘输入字符的,但是可以粘贴,这说明是被过滤掉了,但是返回false是就可以用键盘输入字符。

④voidQObject::installEventFilter(QObject* filterObj )

这个函数是QObject的一个函数,因此可以安装到任何QObject的子类,并不仅仅是UI组件。这个函数接收一个QObject对象,调用了这个函数安装事件过滤器的组件会调用filterObj定义的eventFilter()函数。例如,textField.installEventFilter(obj),则如果有事件发送到textField组件是,会先调用obj->eventFilter()函数,然后才会调用textField.event()。

我们可以向一个对象上面安装多个事件处理器,只要调用多次 installEventFilter()函数。如果一个对象存在多个事件过滤器,那么,最后一个安装的会第一个执行,也就是后进先执行的顺序。一般这个函数的调用时在构造函数里面:

⑤如果你在事件过滤器中 delete了某个接收组件,务必将函数返回值设为 true。否则,Qt还是会将事件分发给这个接收组件,从而导致程序崩溃。

事件过滤器和被安装过滤器的组件必须在同一线程,否则,过滤器将不起作用。另外,如果在安装过滤器之后,这两个组件到了不同的线程,那么,只有等到二者重新回到同一线程的时候过滤器才会有效。(大牛解释是:事件过滤器和安装过滤器的组件必须在同一线程。Qt 里面,对象创建之后,可以使用 moveToThread() 函数将一个对象移动到另外的线程。在这种情形下(当然,事件过滤器必须在同一线程时才能被正确安装,这是第一句话说明的),在它们分属在不同线程时,事件过滤器也是不起作用的,只用当它们重新回到同一线程(使用 moveToThread() 或者是线程自然结束)时,过滤器才能重新工作。)

⑥如果使用 installEventFilter() 函数给一个对象安装事件过滤器,那么该事件过滤器只对该对象有效,只有这个对象的事件需要先传递给事件过滤器的 eventFilter() 函数进行过滤,其它对象不受影响。

⑦如果给 QApplication 对象安装事件过滤器,那么该过滤器对程序中的每一个对象都有效,任何对象的事件都是先传给 eventFilter() 函数而且第一个获得该事件。

⑧事件的分发既可以是同步的,又可以是异步的,而函数的调用或者说是槽的回调总是同步的。事件的另外一个好处是,它可以使用过滤器。

void QObject::installEventFilter(QObject * filterObj)
Installs an event filter filterObj on this object. For example:

An event filter is an object that receives all events that are sent to this object. The filter can either stop the event or forward it to this object. The event filter filterObj receives events via its eventFilter() function. TheeventFilter() function must return true if the event should be filtered, (i.e. stopped); otherwise it must return false.

If multiple event filters are installed on a single object, the filter that was installed last is activated first.

Here‘s a KeyPressEater class that eats the key presses of its monitored objects:

And here‘s how to install it on two widgets:

The QShortcut class, for example, uses this technique to intercept shortcut key presses.

Warning: If you delete the receiver object in your eventFilter() function, be sure to return true. If you return false, Qt sends the event to the deleted object and the program will crash.

Note that the filtering object must be in the same thread as this object. IffilterObj is in a different thread, this function does nothing. If either filterObjor this object are moved to a different thread after calling this function, the event filter will not be called until both objects have the same thread affinity again (it is not removed).
---------------------
作者:helmsgao
来源:CSDN
原文:https://blog.csdn.net/love_gaohz/article/details/10496631
版权声明:本文为博主原创文章,转载请附上博文链接!

原文地址:https://www.cnblogs.com/findumars/p/10355738.html

时间: 2024-10-12 19:14:05

installEventFilter可以安装到任何QObject的子类,并不仅仅是UI组件。事件过滤器和安装过滤器的组件必须在同一线程,在它们分属在不同线程时,事件过滤器也是不起作用的的相关文章

2019.7.01—双硬盘安装Win10,Ubuntu18.04双系统(包括Ubuntu系统美化;安装QQ,微信;配置酸酸.乳)

这篇文章侧重于介绍双系统中Ubuntu系统的安装与配置,windows系统的安装较略.有些方法可能对你的机器不管用,那就要自行百度啦(^_^). 先放一张Ubuntu系统的成品照: 本人电脑配置情况:华硕w50j(老机器了= =),12g内存,500G固态硬盘+1T机械硬盘 总体目标:不使用任何第三方装机软件完成Win10及Ubuntu18.04纯净系统的安装,并完成Ubuntu系统的相关配置. 具体目标:固态中分350g给windows用于安装系统,其余用于安装Ubuntu系统:机械盘中分60

离线安装SharePoint 2013必备组件,AppFabric安装错误问题解决

背景:要安装SharePoint的Windows 2012 Server在IDC机房,无法使用产品准备工具在线安装诸多依赖的必备组件 问题:SharePoint 2013的部分必备组件间存在依赖关系,若安装失败只要调整顺序即可,但AppFabric安装错误很难解决 现象: 1.只选择默认功能时安装AppFabric可以成功,但SharePoint安装程序会因组件不完整无法进行下去 2.选择所有功能安装AppFabric会报错误:“由于安装程序MSI返回错误代码1603,因此,AppFabric安

在虚拟机里安装centos 6.4和centos 5.8里配置vim 7.4安装过程

下是centos 6.4里安装vim配置操作命令 [BEGIN] 2014/5/13 星期二 上午 10:08:54 [[email protected] ~]# rpm -qa | grep vim [[email protected] ~]# yum remove vim vim-enhanced vim-common vim-minimal [[email protected] ~]# wget ftp://ftp.vim.org/pub/vim/unix/vim-7.4.tar.bz2

Dell R420安装Debian6.0.2 amd64和Debian6.0.2_i386系统后网卡驱动安装

最近一个公司里的古老项目重新上线运行,用的操作系统版本低,是Debian6.0.2_i386的,服务器是Dell R420的这样就出现了系统安装后无法找到网卡驱动的问题,本文记录下来,要不以后找不到了. ### 网卡驱动下载 http://down.51cto.com/data/2274577 ### For Debian6.0.2_amd64 # apt-get install  build-essential # unmae -r   //得到内核版本信息,例如:2.6.32-5-amd64

Android菜鸟笔记- 获取未安装的APK图标、版本、包名、名称、是否安装、安装、打开

周末闲来无事,把Android的基础知识拿出来复习复习,今天主题是<获取未安装的APK图标.版本.包名.名称.是否安装.跳转安装.打开> 一.获取APK图标 通常读取APK的图标可以用,PackageManager里面的getApplicationIcon(ApplicationInfo)来得到一个drawable.但实际使用的时候经常只能得到一个默认的图标,根本不是APK的图标. 参考小米开源文件管理器,结合实践,代码如下: /* * 采用了新的办法获取APK图标,之前的失败是因为andro

SharePoint 2013必备组件离线包安装:AppFabric无法安装问题解决

由于没有网络,无法使用sharepoint2013的安装必备软件的在线下载向导安装,当要安装 SharePoint 2013 的服务器与 Internet 隔离时,通常需要从脱机位置安装必备组件.即使不属于这种情况,从集中脱机位置安装必备组件也可以使您安装已知的受控映像集,从而确保场服务器的一致性.如下图: 必须把SP2013的必备组件全部下载下来,进行离线安装,组件如下: Microsoft .NET Framework 4.5 版 Windows Management Framework 3

Android菜鸟笔记- 获取未安装的APK图标、版本号、包名、名称、是否安装、安装、打开

周末闲来无事,把Android的基础知识拿出来复习复习,今天主题是<获取未安装的APK图标.版本号.包名.名称.是否安装.跳转安装.打开> 一.获取APK图标 通常读取APK的图标能够用,PackageManager里面的getApplicationIcon(ApplicationInfo)来得到一个drawable.但实际使用的时候常常仅仅能得到一个默认的图标.根本不是APK的图标. 參考小米开源文件管理器,结合实践,代码例如以下: /* * 採用了新的办法获取APK图标.之前的失败是由于a

安装程序无法验证是否已安装所需Microsoft更新KB2919355,如果存在此更新,请继续安装。

VMware 中Windows2012 R2安装VMwareTools 安装Tools时提示"安装程序无法验证是否已安装所需Microsoft更新KB2919355,如果存在此更新,请继续安装.", 如下图: 这是因为Windows2012R2缺少两个更新补丁 请按照顺序更新补丁: 1.安装KB2975061更新 下载Windows Server 2012 R2 更新程序 (KB2975061)并更新安装. 2.安装KB2919355更新 下载 Windows Server 2012

(转)Delphi7中QuickReport组件(QReport报表)安装方法及重要属性

Delphi7中没有办法直接使用QuickReport组件,因为在Delphi7中没有将QuickReport组件包作为默认组件打包,如果要使用此组件,需要先安装一下. 打开delphi7,点Component->Install Packages(安装包),在打开窗口中,点"Add"按钮,然后在delphi7\Bin文件夹里,找到dclqrt70.dpl文件,双击即可,再点击“OK”即可完成安装.在组件工具栏中最后一个就是新添加的QReport报表组件. QuickReport重