QT事件机制

Qt事件分类

  • Spontaneous 事件

    由窗口系统产生,它们被放到系统队列中,通过事件循环逐个处理。

    本类事件通常是Windows System把从系统得到的消息,比如鼠标按键、键盘按键等, 放入系统的消息队列中。 Qt事件循环的时候读取这些事件,转化为QEvent,再依次逐个处理。

  • Posted 事件

    由Qt或应用程序产生,它们被Qt组成队列,再通过事件循环处理。

    调用QApplication::postEvent()来产生一个posted类型事件。

    例如:QWidget::update()函数,当需要重新绘制屏幕时,程序调用update()函数。其实现的原理是new出一个paintEvent,调用 QApplication::postEvent(),将其放入Qt的消息队列中,等待依次被处理。

  • Send事件

    由Qt或应用程序产生,但它们被直接发送到目标对象。

    调用QApplication::sendEvent()函数来产生一个send类型事件。

    send 类型事件不会放入队列, 而是直接被派发和处理, QWidget::repaint()函数用的就是这种方式。

QObject类

QObject三大职责

  • 内存管理

  • 内省(intropection)

  • 事件处理机制

任何一个想要接受并处理事件的对象均须继承自QObject,可以重写QObject::event() 来处理事件,也可以由父类处理。

事件处理与过滤

Qt提供了5个级别来处理和过滤事件。

  • 重新实现特定的event handler
    重新实现像mousePressEvent(), keyPressEvent()和paintEvent()这样的event Handler是目前处理event最普通的方式。

  • 重新实现QObject::event()
    通过重新实现event(),我们可以在事件到达特定的event handler之前对它们作出处理。

  • 安装一个event filter到一个单独的QObject
    一个对象用installEventFilter注册了, 发到目标对象的所有事件都会先发到监测对象的eventFilter()。如果同一个object安装了多个event filter, filter会依次被激活, 从最近安装的回到第一个。

    例如:
    textField.installEventFilter(obj),如果有事件发送到textField组件时,会先调用obj->eventFilter()函数,然后才会调用textField.event()。

  • 在QApplication对象上安装event filter
    一个event filter被注册到唯一的QApplication对象, 程序里发到每个对象的每个事件在发到其他event filter之前,都要首先发到这个eventFilter()。

  • 子类化QApplication并重新实现notify()
    Qt调用QApplication::notify()来发出事件,在任何event filter得到之前, 重新实现这个函数可以得到所有事件。

自定义事件

阻塞型事件:事件发送后需要等待处理完成

bool QCoreApplication::sendEvent(QObject *receiver, QEvent *event)

事件生命周期由应用程序自身管理,同时支持栈事件对象和堆事件对象的发送。

非阻塞型发送:事件发送后立刻返回,事件被发送到事件队列等待处理

void QCoreApplication::postEvent(QObject *receiver, QEvent *event, int priority = Qt::NormalEventPriority)

只能发送堆事件对象,事件被处理后由Qt平台销毁。

事件的传递

对于某些会被转发的事件, 包括: 鼠标、滚轮、按键等事件。如果在整个事件的派发过程结束后还没有被处理, 那么这个事件将会向上转发给它的父widget,直到最顶层窗口。

比如:事件可能最先发送给QCheckBox, 如果QCheckBox没有处理, 那么由QGroupBox接着处理;如果QGroupBox仍然没有处理, 再送到QDialog, 因为QDialog已经是最顶层widget, 所以如果QDialog再不处理, QEvent将停止转发。

如何终止事件传递?

QApplication::notify(), QObject::eventFilter(), QObject::event() 通过返回bool值来表示是否继续传递。“真”表示已经处理,不再传递, “假”表示事件需要继续传递。

另一种是调用QEvent::accept() 或 QEvent::ignore()对事件进行标识。前者用来告诉Qt,事件处理函数“接收”了这个事件,不要再传递;后者则告诉Qt,事件处理函数“忽略”了这个事件,需要继续传递。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
9.1事件机制与原理分析 9.1.1 什么是Qt事件驱动?         我们在写Qt工程类项目的时候都会发现,主程序里面都有这么一段代码: int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); } 有点抽象,Qt进行了封装        实际上a.exec()便是Qt程序进入事件消息循环, 9.1.2 图形界面应用程序的消息处理模型 回调、os的魔抓windows、linux,从用户层到 内核层,如何管理进程、线程、 Os如何处理、底层机制 特点: 基于操作系统才能运行 GUI应用程序提供的功能必须由用户触发 用户操作界面时操作系统是第一个感知的  系统内核的消息通过事件处理转变成QT的信号 9.1.3 Qt中的事件处理 (1)在Qt中,事件被封装成一个个对象,所有的事件均继承自抽象类QEvent.              事件处理的核心包括事件①产生、②分发、③接受和处理 ①事件的产生 谁来产生事件? 最容易想到的是我们的输入设备,比如键盘、鼠标产生的 keyPressEvent,keyReleaseEvent, mousePressEvent,mouseReleaseEvent事件 (被封装成QMouseEvent和QKeyEvent)。 ②Qt事件的分发 谁来负责分发事件? 对于non-GUI的Qt程序,是由QCoreApplication负责将QEvent分发给QObject的子类-Receiver.  对于Qt GUI程序,由QApplication来负责   ③事件的接受和处理 谁来接受和处理事件? 答案是QObject。 类是整个Qt对象模型的心脏,事件处理机制是QObject三大职责( 内存管理、内省intropection、事件处理制)之一。 任何一个想要接受并处理事件的对象均须继承自QObject,可以选择重载QObject::event()函数或事件的处理权转给父类。 9.1.4 QObject的内省机制

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值