Qt 事件处理机制的深入理解

762 篇文章 203 订阅
订阅专栏
Qt中的事件来源于程序内外,多数来自操作系统。事件由QObject接收,通过事件循环进行处理。sendEvent是同步事件,postEvent是异步事件。事件过滤器允许对象监听和拦截其他对象的事件。event方法用于事件分发,而accept()和ignore()决定事件是否传递给父窗口。
摘要由CSDN通过智能技术生成

1.Qt中事件的来源,谁接收处理。

Qt中事件的来源有两个:程序外部和内部,多数情况下来自操作系统,可以通过bool QEvent::spontaneous() const函数来获知,返回true,事件发生在应用程序之外(系统事件),否则返回false。

事件由QObject类来接收,是Qt对象模型的核心,所有需要处理的事件类都必须继承QObject。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

2.事件处理顺序

首先QCoreApplication::exec()开启了事件循环,一直到QCoreApplication::exit()被调用才终止,所以说事件循环是伴随着Qt程序的整个运行周期,事件被分发到事件队列中,当队列中有事件时会不停的将事件发送给QObject对象,队列为空时就阻塞,以下为处理顺序。

 

  • sendEvent:使用notify()函数直接将事件发送给接收者,发送事件时不会删除该事件,通常是在栈上面创建事件,它是同步事件。
  • postEvent:将事件添加到事件队列中,并立即返回;事件必须在堆上分配,因为提交事件队列将获得事件的所有权,并在提交后删除它。在事件发布后访问该事件是不安全的,它是异步事件。

示例:

 

void Widget::on_pushButton_clicked()
{
    QKeyEvent eventPress(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
    QApplication::sendEvent(ui->label, &eventPress);
}
 
void Widget::on_pushButton_2_clicked()
{
    QKeyEvent *eventPress = new QKeyEvent(QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
    QApplication::postEvent(ui->label, eventPress);
}

点击上图中按钮会发送QLabel标签的键盘按下tab键事件,我自定义了一个WLabel类继承自QLabel,重写了event方法。

bool WLabel::event(QEvent *e)
{
 
    if(e->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = (QKeyEvent*)e;
        if(keyEvent->key() == Qt::Key_Tab)
        {
            qDebug()<<"press tab key";
            return ture;
        }
    }
 
    return QLabel::event(e);
}

事件会发送到WLabel类的event方法中,会打印出下面的结果。

 

3.事件过滤器

事件的传送和处理流程的第一站是事件过滤器eventFilter(),某个对象A可以通过给另一个对象B安装事件处理器,实现对对象B事件的监听或者拦截功能。我们可以给A取名监听器,B取名接收器。一个对象可以监听多个对象,一个对象也可以被多个事件监听。事件过滤器返回true则表示事件已经处理完毕,否则传递给下一个监听器或者接收器本身。

void QObject::installEventFilter(QObject *filterObj)
bool eventFilter(QObject *obj, QEvent *event);

Qt的事件过滤由以上两个方法实现,首先安装一个事件过滤器,然后重写bool eventFilter(QObject *obj, QEvent *event)。

filterObj表示事件筛选器对象,它接收发送到此QObject对象的所有事件。筛选器可以停止事件,也可以将事件转发给此QObject对象。事件过滤器filterObj通过它的eventFilter()函数接收事件。

eventFilter()有返回值。

  • 如果返回true,表示事件过滤,不会发送到对象本身。
  • 如果返回false,表示事件未过滤,会通过event()方法将事件分发到对象。
  • 返回给基类进行处理,例:return QObject::eventFilter(obj, event)。

4.event方法

当经过事件过滤器后,未过滤掉的事件会进入到event方法中,event()函数主要用于事件的分发。所以,如果你希望在事件分发之前做一些操作,就可以在派生类中重写这个event()函数。

例:实现一些鼠标进出的打印,键盘按键一些打印。

bool WLabel::event(QEvent *e)
{
    if(e->type() == QEvent::Enter)
    {
        qDebug()<<"WLabel event :enter";
        return true;
    }
    else if(e->type() == QEvent::Leave)
    {
        qDebug()<<"WLabel event :Leave";
        return true;
    }
    else if(e->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = (QKeyEvent*)e;
        if(keyEvent->key() == Qt::Key_Tab)
        {
            qDebug()<<"press tab key";
            return true;
        }
    }
 
    return QLabel::event(e);
}

上述代码中event如果事件e被识别并处理,则应返回true,否则交给它的基类QLabel来处理。

5.鼠标进入事件

bool WLabel::event(QEvent *e)
{
    if(e->type() == QEvent::Enter)
    {
        qDebug()<<"WLabel event :enter";
    }
    return QLabel::event(e);
}

上述代码,

  • 如果事件返回return QLabel::event(e),会将鼠标进入事件分发到 enterEvent(QEvent *event),会打印下面的语句。
  • 如果打印语句后面 return ture,则不会将事件传递到enterEvent中。
void WLabel::enterEvent(QEvent *event)
{
    qDebug()<<"WLabel enterEvent";
}

6.accept(),ignore()

在我们做UI界面时,经常会重写mousePressEvent,wheelEvent等函数,根据不同情况要对事件event进行特殊处理。

当执行event->accept()时,意味着这次的事件已经被“我”接受啦,只有我使用。

当执行event->ignore()时,意味着这次的事件“我”不要接受他,函数执行完event给我的父窗口,他会需要的。

差别也就是要不要传递给父窗口,accept不传递,ignore传递,注意是父窗口,不是基类。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

Qt事件处理流程
weixin_41502364的博客
05-14 1743
Qt事件处理 Qt事件处理大概大概可以分为四个步骤: 事件派发 ->事件过滤 ->事件分发 ->事件处理 事件派发:事件派发 是由Qt框架(QApplication 对象)来完成的,它将当前应用程序产生的事件派发给对应的窗口 事件过滤:事件在到达对应的窗口之前,可以被其他对象过滤、拦截、处理 事件分发:每个窗口都会有一个事件分发器,事件分发器会对时间进行分类,再将分好类的事件分发给对应的事件处理函数进行处理,每个事件处理函数的功能其实是非常单一的,只处理当前这一类事
QT】事件分发器
StudyWinter的博客
10-31 219
event事件分发器,用于分发事件,在这里也可以做拦截,返回值boo。如果返回的是true代表拦截处理,不再向下分发。.h文件中声明该函数。
Qt事件处理汇总
qq_31286321的博客
06-23 1500
QT事件产生后会被立即发送到相应的QWidget对象相应的QWidget中的event(QEvent *)进行事件处理event(QEvent *)根据事件类型调用不同的事件处理函数在事件处理函数中发送QT预定义的信号调用信号关联的槽函数public:protected:elseMain.cpp编译运行程序,鼠标点击按钮后打印出“Left press”字符串,没有打印出“child clicked”字符串。
qt事件的触发原理与事件传递顺序
biao2488890051的博客
12-25 2215
用户键盘或者鼠标输入 操作系统内核检测到,把这些事件放进一个缓冲队列里 qt应用程序的事件循环函数在不停的检查这个缓冲队列里是否有新的事件 检测到了,则判断该事件产生的屏幕坐标,发送给对应的窗口部件 每个窗口部件都是继承于QObject类,这个类里就包含了事件处理相关(QEvent类)的虚函数(鼠标按下,鼠标释放等等),然后调用这些虚函数(很多虚函数默认是会调用一个钩子函数的,这就是信号发射) 根据C++虚函数原理,子类重写的这些事件处理虚函数,会得到真正的执行了。 qt事件处理相关需要注意的
Qt事件处理的顺序
迎风的舵手
07-08 2270
<br />1.事件首先由Qt的ServerApplication去接收来自于外部或内部的一些行为,鼠标点击,键盘输入,时钟事件等,分析并决定送往对应的对象去处理(内部管理机制,如有机会另文分析),最后会调用bool QCoreApplication::notify ( QObject * receiver, QEvent * event ) [virtual]去处理,当然这个是虚函数,你可以在子类去重新实现它 。<br /> <br />2.在notify(…)中,在发给对应的接收者前,会先把消息送给QA
Qt 事件处理机制 (下篇) - 51CTO.COM1
08-04
在这一部分中,我们将继续围绕Qt事件处理机制展开讨论,重点关注`QApplication::exec()`、`QCoreApplication::exec()`以及`QEventLoop::exec()`等关键函数的作用与实现细节,并深入分析Qt应用程序如何将事件分发给...
Qt事件处理之鼠标处理事件
08-21
你可以通过查看和运行这个例子来更深入地理解Qt事件处理机制。 总结,Qt事件处理是其强大的面向对象特性的体现,通过重写特定的事件处理函数,我们可以轻松地响应用户的各种交互。理解并熟练运用这些事件处理机制,...
QT事件处理机制
09-19
### QT事件处理机制 #### 一、概述 在探讨QT事件处理机制之前,我们需要先理解事件在软件开发中的重要性。事件是程序与用户的交互桥梁,...总之,深入理解QT事件处理机制对于开发高质量的GUI应用程序至关重要。
QT事件系统一:父子组件之间的事件传播机制
06-23
QT事件系统是Qt库中的核心特性之一,它使得在图形用户界面编程中处理用户交互变得简单而高效。本文将深入探讨“QT事件系统一:父子...通过深入理解和熟练运用这些机制,我们可以构建出更加智能和用户友好的应用程序。
QT事件处理系统之二:窗口部件的事件拦截,以及事件的传递顺序
最新发布
06-23
QT事件处理系统是Qt库中的核心机制之一,它使得开发者能够对用户交互、系统通知以及其他各种事件进行响应。本文将深入探讨窗口部件的事件拦截和事件的传递顺序,以帮助理解如何在Qt应用程序中实现精细化的事件管理。...
Qt事件处理的方法
chenlong12580的专栏
07-05 1万+
一、Qt事件处理的方式   1、事件处理模式一         首先是事件源产生事件,最后是事件处理器对这些事件进行处理。然而也许大家会问, Qt中有这么多类的事件,我们怎么样比较简便的处理每个事件呢?设想,如果是每个事件都对应同一个事件处理器,在该事件处理器中对不同的事件进行分类处理,这样的弊端有两点:第一,导致该事件处理器过于臃肿复杂;第二,这样不便于扩展,当系统新增加事件类型或
Qt事件处理机制整个流程--以鼠标在一个窗口中点击为例
热门推荐
zgrjkflmkyc的专栏
03-13 1万+
转载自:http://mobile.51cto.com/symbian-272812.htm,在此谢谢原作者的分享! ------------------------第一部分---------------------- 本篇来介绍Qt 事件处理机制 。深入了解事件处理系统对于每个学习Qt人来说非常重要,可以说,Qt是以事件驱动的UI工具集。 大家熟知Signals/Slots在多线
C++ GUI Qt4编程-事件处理
u011014707的专栏
02-27 1938
事件(event)是由窗口系统或者Qt自身产生的,用以响应所发生的各类事情。当用户按下或者松开键盘或者鼠标上的按键时,就可以产生一个键盘或者鼠标事件;当某个窗口第一次显示的时候,就会产生一个绘制事件,用来告知窗口需要重新绘制它本身,从而使得该窗口可见。大多数事件是作为用户动作的响应而产生的,但是也有一些例外,比如像定时器事件,则是有系统独立产生的。         不应该混淆"事件"和"信号"这
Qt中的事件处理机制(event)
从0开始学编程
10-19 4142
Qt事件也就是Qt程序中出现的一系列“事情”,包括对用户操作做出反应时发出的鼠标或键盘事件等;以及系统内部自动发出的定时器事件等。总之,出现了这些事件后就需要对这些事件进行处理,处理的方法便是“事件处理机制”。 图1 Qt事件产生 以用户操作事件为例,其事件处理过程如下图。 图2 Qt事件处理过程 上述过程通过操作系统和Qt平台的处理,将用户具体的一个操作指令(如鼠标点击)转化为一个Q...
Qt事件发生的先后顺序
Qt君
01-04 2389
Qt事件发生的先后顺序:   1.子类化QApplication并且重新实现notify();   2.在QApplication对象中安装事件过滤器;   3.在QObject中安装事件过滤器;   4.重新实现QObject::event();   5.重新实现某些特定的事件(如paintEvent等)....
Qt事件处理的顺序
qigeyue的博客
08-14 1058
Qt事件处理,实际上是有五个层次: 1. 重写paintEvent()、mouseXXXEvent()等事件处理函数。这是最普通、最简单的形式,同时功能也最简单。 2. 重写event()函数。event()函数是所有对象的事件入口,QObject和QWidget中的实现,默认是把事件传递给特定的事件处理函数。 3. 在特定对象上面安装事件过滤器。该过滤器仅过滤该对象接收到的事件...
Qt事件处理流程详解
风起时~微凉的博客
06-21 2021
本文主要对Qt的一些事件处理,做一个介绍: 事件流程图: 1、事件产生 1)QApplication::postEvent():调用 QApplication::postEvent(),将其放入Qt的消息队列中,依次等待被处理;postEvent()中事件对象的生命周期由Qt平台管理,只支持分配在堆上的事件对象,事件被处理后由Qt平台销毁。这种方式是异步处理事件,Qt的事件循环是异步的,当调用QApplication::exec()时,就进入了事件循环,先处理Qt事件队列中的事件, 直至为空,再处理系统消
Qt事件处理(四)——重写event()函数
simon曦的博客
12-09 1万+
目录目录 前言 Qt的事件分发过程 重新实现event 代码 总结前言根据视频看的事件处理,但是没有顺序,所以有点乱!不过理解起来也不麻烦!学习!分享!感谢!Qt的事件分发过程 在QApplication::exec()的事件循环中,会不断判断事件的产生,然后把产生的事件分派给对应的控件。比如,在QPushButton中产生了keyPressEvent()事件,这时候QApplication::e
QT事件处理机制详解
理解这一机制对于深入学习和开发基于Qt的应用程序至关重要。 首先,让我们来了解什么是事件。在Qt中,事件是由窗口系统或Qt自身生成的,用于响应各种操作或状态变化。例如,当用户按下键盘或鼠标,窗口系统会生成...
写文章

热门文章

  • Qt QString字符串分割、截取的3种方法 22998
  • Qt QWidget颜色设置的三种方法 14123
  • rtsp协议详解-最详细的流媒体传输协议 11155
  • 成为Qt开发大牛,从入门到精通,一步一步走完整个学习路线! 10473
  • Qt comboBox控件的三种基本用法 9484

分类专栏

  • QT开发 762篇
  • C++Linux后端 20篇
  • 音视频开发 140篇

最新评论

  • Qt QUndoStack、QUndoCommand(实现撤回和回撤)

    Aliiiiii: 为什么代码跑通后矩形不显示? 求教

  • 嵌入式音视频开发需要掌握哪些技能点?

    瓦斯科0.0: 我咋没找到这个项目

  • android webrtc入门教程一(简单一对一通话实现)

    无极无法: 为什么远程wifi连接不能视频,局域网连接wifi正常

  • 前端使用ffmpeg压缩视频

    橙子yq: 请问支持uniapp的h5项目使用吗?目前试了报错@ffmpeg_ffmpeg.js?v=4d909bd3:820 Uncaught ReferenceError: createFFmpegCore is not defined, 请帮忙看看

  • OpenCV 图像拼接和图像融合技术

    这颗: 一次拼接多张图能实现吗?

最新文章

  • 八个 C++ 开源项目,帮助初学者进阶成长
  • QT 实现五子棋
  • C++音视频毕设项目计划书
2024
09月 5篇
08月 8篇
07月 7篇
06月 13篇
05月 10篇
04月 13篇
03月 18篇
02月 10篇
01月 19篇
2023年578篇
2022年229篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

玻璃钢生产厂家雕塑白菜玻璃钢图片福州玻璃钢牛雕塑苏州玻璃钢花盆设计厂家漯河不锈钢水景玻璃钢彩绘雕塑龙井市政用玻璃钢花盆批发玻璃钢人物雕塑阳泉玻璃钢卡通雕塑定制扶沟玻璃钢雕塑岳阳衡阳玻璃钢雕塑定制成都玻璃钢雕塑哪家好黄山玻璃钢雕塑市场陕西公园玻璃钢雕塑芜湖景区玻璃钢雕塑价位滨州市玻璃钢雕塑深圳玻璃钢花盆价格潞城玻璃钢马雕塑玻璃钢花盆室外能用几年透明玻璃钢雕塑安宁市玻璃钢雕塑定做玻璃钢雕塑十二生肖哪家有个旧市玻璃钢雕塑设计防城港玻璃钢雕塑生产厂家南京玻璃钢雕塑公司洛阳锻铜玻璃钢仿铜雕塑价格广东大型商场美陈订购昌都商场美陈梅州玻璃钢景观雕塑造型精美内江玻璃钢雕塑摆件施工工程玻璃钢雕塑用什么树脂德州玻璃钢仿铜雕塑定制厂家香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化