QT事件机制总结

QT事件机制个人理解

事件驱动是QT软件的生命,在基于QT的软件开发过程中,经常会涉及到事件相关的概念和过程,因此QT程序员们有必要对QT的事件机制有一定程度的了解。本文试图总结一下个人对QT事件机制的认识,以便今后可以经常拿来参考。主要涉及一下几个方面:

  • 事件驱动
  • 事件循环
  • 事件派发、处理
  • 事件发送
  • 事件转发、已处理标志

事件

可以理解为消息,当系统状态达到某种条件(可自定义),即可产生(创建)一种相应的消息(事件)。

事件驱动

QT是事件驱动的系统,即没有事件发生时,系统是静止的!发生了事件,系统就派发事件、处理时间。(这样一来,系统就能够响应用户操作)
用户操作或系统本身产生事件,然后经过事件派发,目标对象收到并响应事件。
因此,每个QT程序都需要监听事件,并将事件传送给目标。
QT是如何实现这一步骤的呢?
首先需要有一个缓冲区来存储新产生的事件,叫事件队列;系统不断将新产生的事件加入到这个队列中(这一过程由系统维护),然后,不断从事件队列中取出事件,进行事件派发和处理
在执行 exec() 函数之后,程序 将进入事件循环来监听应用程序的事件。当事件发生(软件环境达到一定条件)时,Qt 将创建一个事件(消息)对象,并将此事件对象发送到指定目标来处理(响应)。

事件循环

exec() 函数中,QT通过不断监听事件队列来派发事件。由于通过循环来实现,因而常叫事件循环。
while ( !app_exit_loop )
{
while( !postedEvents ) { processPostedEvents() }
while( !qwsEvnts ){ qwsProcessEvents(); }
while( !postedEvents ) { processPostedEvents() }
}

发送事件

1、QApplication::sendEvent直接通过Notify发送event(栈上)到reciever
2、QApplication::postEvent现将事件传到事件队列,然后处理到该事件(堆上)时,由Notify发送到reciever

事件派发

由Notify(QObject receiver, QEvent event) 实现
过程:
1、首先逐个(栈顺序:队尾先)发送给程序间谍:由间谍的eventFilter()处理
2、然后逐个发送给目标间谍:同上
3、最后发送到目标,由目标的event()处理

bool QCoreApplicationPrivate::notify_helper(QObject *receiver, QEvent * event)  
{  
    // send to all application event filters  
    if (sendThroughApplicationEventFilters</span>(receiver, event))  //程序间谍优先
        return true;  
    // send to all receiver event filters  
    if (sendThroughObjectEventFilters</span>(receiver, event))  //目标间谍次之
        return true;  
    // deliver the event  
    return receiver->event</span>(event);  //目标
}  

事件响应

1、eventFilter():内线事件响应
要监听谁的事件,就在他内部安插内线(间谍)!自己通过eventFilter()函数接收事件消息,想要截断消息就返回true,否则返回false
2、event():事件分类处理
根据QEvent的类型, 调用相应的特定事件处理函数

事件转发&已处理标志

1、事件转发
对于某些类别的事件, 如果在整个事件的派发过程结束后还没有被处理, 那么这个事件将会向上转发给它的父widget, 直到最顶层窗口. 如图所示, 事件最先发送给QCheckBox, 如果QCheckBox没有处理, 那么由QGroupBox接着处理, 如果QGroupBox没有处理, 再送到QDialog, 因为QDialog已经是最顶层widget, 所以如果QDialog不处理, QEvent将停止转发.
2、事件处理标志
如何判断一个事件是否被处理了呢? Qt中和事件相关的函数通过两种方式相互通信. QApplication::notify(), QObject::eventFilter(), QObject::event() 通过返回bool值来表示是否已处理. “真”表示已经处理, “假”表示事件需要继续传递. 另一种是调用QEvent::ignore() 或 QEvent::accept() 对事件进行标识. 这种方式只用于event() 函数和特定事件处理函数之间的沟通. 而且只有用在某些类别事件上是有意义的, 这些事件就是上面提到的那些会被转发的事件, 包括: 鼠标, 滚轮, 按键等事件.


应用

事件的大多数应用主要在于监听特定的事件,大致可以通过如下几种方式来进行:
A、安插间谍,实现eventFilter()函数:
[] 给app安插间谍
[] 给目标对象安插间谍
B、继承目标类(继承了QObject):
[] 重载event()函数
[] 重载事件响应函数handdler
C、重载QApplication::Notify()函数

事件路由:app.Notify()–>app.filterList.eventFilter()–>reciver.filterList.eventFilter()–>reciver.event()–>reciever.eventHanddler()


  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值