Qt-事件与信号

事件和信号的区别在于,事件通常是由窗口系统或应用程序产生的,信号则是Qt定义或用户自定义的。Qt为界面组件定义的信号往往通常是对事件的封装,如QPushButton的clicked()信号可以看做对QEvent::MouseButtonRelease类事件的封装。

在使用界面组件作为交互操作编程的时候,我们通常选择合适的信号,为该信号编写槽函数。但是Qt的界面组件只将少数事件进行封装成了信号,对于某些事件可能缺少对应的信号,例如QLabel的信号中就没有与双击鼠标对应的信号

在这种情况下我们可以从QLabel继承定义一个新的标签类,通过自定义信号和事件处理,使新的标签类具有处理鼠标双击事件的信号。

函数event()的作用

应用程序派发给界面组件的事件首先会由其函数event()处理,如果函数event()不做任何处理,组件就会自动调用QWidget中与事件类型对应的默认事件处理函数,从QWidget派生的界面组件一般不需要重新实现函数event(),如果对某种事件进行处理,可以重新实现其对应的事件处理函数。

QWidget类针对一些典型事件编写了事件处理函数,但是某些类型的事件没有对应的事件处理函数,例如,对于QEvent::HoverEnter和QEvent::HoverLeave类型的事件,QWidget类中就没有对应的事件处理函数,这种情况下,如果要对QEvent::HoveEnter和QEvent::HoveLeave类型的事件进行处理,就需要自定义一个类,重新实现函数event(),判断事件类型,针对QEvent::HoveEnter和QEvent::HoveLeave类型的事件进行对应的处理。

注意,TMyLabel中的构造函数我是改变了其中参数的,因为使用创建C++类向导自动生成的TMyLabel的构造函数是没有任何参数的,这样是不对的,因为界面组件必须要有一个父容器组件

注意在构造函数中我们将TMyLabel的Qt::WA_Hover属性设置为true(默认值是false)。这样鼠标光标移入和移出才会分别产生QEvent::HoveEnter和QEvent::HoveLeave类型的事件。

事件过滤器

一个界面组件如果要对事件进行处理,需要从父类继承定义一个新类,在新类里编写程序直接处理事件,或者将事件转换成信号。
如果不想定义一个新的类,可以用事件过滤器对界面组件的事件进行处理。事件过滤器是QObject提供的一种处理事件的方法,它可以将一个对象的事件委托给另一个对象来监听并处理。

事件过滤器工作原理

QObject提供了一种处理事件的方法,事件过滤器。它可以将一个对象的事件委托给另一个对象来监视并处理。例如,一个窗口可以作为其他界面上的QLabel组件的事件过滤器,派发给QLabel组件的事件由窗口去处理,这样,就不需要为了处理某种事件而新定义一个标签类。
要实现事件过滤器功能,需要完成两项操作。
(1)被监视对象使用函数installEventFilter()将自己注册给监视对象,监视对象就是事件过滤器。
(2)监视对象重新实现eventFilter()函数,对监视到的事件进行处理。
installEventFilter()和eventFilter()都是QObject类定义的公有函数,函数installEventFilter()的原型定义如下:

void QObject::installEventFilter(QObject* filterObj)
被监视的对象调用installEventFilter(),将对象filterObj设置为自己的事件过滤器。
函数eventFilter()的原型定义如下:

bool QObject::eventFilter(QObject* watched , QEvent* event)
作为事件过滤器的监视对象需要重新实现eventFilter(),参数watched 是被监视的对象,event是产生的事件。这个函数有一个返回值,如果返回true,事件就不会再传播给其他对象,事件处理结束,如果返回false,事件会继续传播给事件接受者做进一步处理。

注意eventFilter()函数结尾不能直接返回true,如果返回true的话,事件过滤器拦截的事件不会继续传播给被监视对象,而在这个类的eventFilter()函数中,我们只处理了被监视对象的少数几个事件件,例如QEvent::Paint类型的事件就没有处理,程序运行时界面上根本就不显示标签的文字。

注意 QEvent::Enter和QEventLeave两个类型的事件,它们与QEvent::HoverEnter和QEvent::HoverLeave类型的事件功能相似,只是使用Hover事件时,需要将组件的mouseTracking属性设置为true,而使用QEvent::Enter和QEventLeave两个类型的事件时无需设置这个属性

相关推荐
Elihuss1 小时前
ONVIF协议操作摄像头方法
开发语言·php
Swift社区5 小时前
在 Swift 中实现字符串分割问题:以字典中的单词构造句子
开发语言·ios·swift
没头脑的ht5 小时前
Swift内存访问冲突
开发语言·ios·swift
没头脑的ht5 小时前
Swift闭包的本质
开发语言·ios·swift
wjs20245 小时前
Swift 数组
开发语言
stm 学习ing6 小时前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
湫ccc7 小时前
《Python基础》之字符串格式化输出
开发语言·python
mqiqe8 小时前
Python MySQL通过Binlog 获取变更记录 恢复数据
开发语言·python·mysql
AttackingLin8 小时前
2024强网杯--babyheap house of apple2解法
linux·开发语言·python