前言:

不熟悉qt 源码结构的 可以先看这一篇

点我点我点我

写qt 的都知道 以下代码, 这段代码究竟的运行机制是怎么样的
咱们一步一步的看

QApplication a(argc, argv);QWidget w;
w.show();return a.exec();

QApplication 的继承结构先看一下

上图比较清晰了, qapplication 继承于 qguiapplication 继承于 qcoreapplication
然后qt万物继承于qobject 没毛病。

事件机制

都知道windwos 基于消息循环这个消息机制来控制应用程序的界面刷新啊 按钮触发等等
发消息? sendmessage postmessage
这里就不多说了,不清楚的要去看一下

qt 是基于事件循环驱动的 事件? event
sendevent postevent 这个没用过
那mousePressEvent printEvent 都清楚吧

Qt 事件 特别多 QEvent 的定义可以去看下,总有你想要的

win平台下 qt的事件机制 可以简单的理解为 对windows的消息机制做了一层封装

根源还是qt coreapplication 源源不断的接受windows的消息, 然后进行一层的翻译与封装为QEvent
然后再加入自己的事件队列 派发给对应的widget进行处理

exec

翻译来源有道:

进入主事件循环并等待直到调用exit(),然后返回
设置为exit()的值(如果通过调用exit()则为0)
辞职())。

需要调用这个函数来启动事件处理。主要的
事件循环从windwos接收事件并将这些事件分派给
应用程序部件。

ok 这里说的 和我上面说的是一个意思吧

!! 也就是这个exec 就是进入应用程序的主事件循环

1.首先调用父类qguiapp的exec

2.继续调用qgui的父类的exec 也就是 qcoreapp的 上面我有说继承结构

QThreadData *threadData = self->d_func()->threadData;
if (threadData != QThreadData::current()) {

看见没, 必须要在主线程
至于为啥要在主线程 可以去了解下为啥UI只能在主线程
简单说一嘴我理解的
1.基于最底层CPU和GPU 执行命令就是一条一条的, 两个UI 窗口 两个线程的话 还是会有一个处于等待状态
2.如果是多线程的那么会大大提高实现的负责度,线程安全同步互斥等乱七八糟的问题

eventLoop

在继续往下就是QEventLoop 事件循环

这里一直在 处理事件
while
{
processEvents
}

看下他的实现

真正的实现在 QAbstractEventDispatcher::processEvents().

在继续跳没有跳进去

我找到源码 应该是他qeventdispatcher_win_p.h win上面的实现

上面还有hook message 应该跑不了了

通过安装消息钩子 来驱动我们的事件

我把代码索起来了 否则截图截不全

展开看下它的 do while 关键部分

QVarLengthArray<MSG> processedTimers;while (!d->interrupt.load()) {MSG msg;bool haveMessage;if (!(flags & QEventLoop::ExcludeUserInputEvents) && !d->queuedUserInputEvents.isEmpty()) {// process queued user input eventshaveMessage = true;msg = d->queuedUserInputEvents.takeFirst();} else if(!(flags & QEventLoop::ExcludeSocketNotifiers) && !d->queuedSocketEvents.isEmpty()) {// process queued socket eventshaveMessage = true;msg = d->queuedSocketEvents.takeFirst();} else {haveMessage = PeekMessage(&msg, 0, 0, 0, PM_REMOVE);if (haveMessage) {if (flags.testFlag(QEventLoop::ExcludeUserInputEvents)&& isUserInputMessage(msg.message)) {// queue user input events for later processingd->queuedUserInputEvents.append(msg);continue;}if ((flags & QEventLoop::ExcludeSocketNotifiers)&& (msg.message == WM_QT_SOCKETNOTIFIER && msg.hwnd == d->internalHwnd)) {// queue socket events for later processingd->queuedSocketEvents.append(msg);continue;}}}if (!haveMessage) {// no message - check for signalled objectswaitRet = MsgWaitForMultipleObjectsEx(nCount, pHandles, 0, QS_ALLINPUT, MWMO_ALERTABLE);if ((haveMessage = (waitRet == WAIT_OBJECT_0 + nCount))) {// a new message has arrived, process itcontinue;}}if (haveMessage) {// WinCE doesn't support hooks at all, so we have to call this by hand :(if (!d->getMessageHook)(void) qt_GetMessageHook(0, PM_REMOVE, reinterpret_cast<LPARAM>(&msg));if (d->internalHwnd == msg.hwnd && msg.message == WM_QT_SENDPOSTEDEVENTS) {if (seenWM_QT_SENDPOSTEDEVENTS) {// when calling processEvents() "manually", we only want to send posted// events onceneedWM_QT_SENDPOSTEDEVENTS = true;continue;}seenWM_QT_SENDPOSTEDEVENTS = true;} else if (msg.message == WM_TIMER) {// avoid live-lock by keeping track of the timers we've already sentbool found = false;for (int i = 0; !found && i < processedTimers.count(); ++i) {const MSG processed = processedTimers.constData()[i];found = (processed.wParam == msg.wParam && processed.hwnd == msg.hwnd && processed.lParam == msg.lParam);}if (found)continue;processedTimers.append(msg);} else if (msg.message == WM_QUIT) {if (QCoreApplication::instance())QCoreApplication::instance()->quit();return false;}

**TranslateMessage
DispatchMessage
PostMessage
当当当 庐山真面目看完了
从头到尾 串起来了
结束
**

如果你觉得本文对你有用 请给我点个赞 码字不容易啊 谢谢了!

Qt 事件机制源码分析 QApplication exec 源码分析 多图超级详细相关推荐

  1. 11.QT事件机制源码时序分析(下)

    接上一篇文章https://blog.csdn.net/Master_Cui/article/details/109182406,本文继续解析QCoreApplication::sendEvent和Q ...

  2. 玩转Android10源码开发定制(二)之基于Pixel 3手机超级详细演示recovery刷机

    玩转Android10源码开发定制(二)之基于Pixel 3手机超级详细演示recovery刷机 本节主要内容: Pixel 3通过fastboot方式刷入Android 11.0官方工厂镜像 Pix ...

  3. 玩转Android10源码开发定制(二)之基于Pixel 3手机超级详细演示fastboot刷机

    玩转Android10源码开发定制(二)之基于Pixel 3手机超级详细演示fastboot刷机 本节主要内容: Pixel 3通过fastboot方式刷入Android 11.0官方工厂镜像 Pix ...

  4. 9.QT事件机制源码时序分析(上)

    通过上两篇博客https://blog.csdn.net/Master_Cui/article/details/109093845和https://blog.csdn.net/Master_Cui/a ...

  5. 10.QT事件机制源码时序分析(中)

    接上一篇文章https://blog.csdn.net/Master_Cui/article/details/109162220,上篇文章已经说过,在Ubuntu18.04,QT的事件机制实际上是采用 ...

  6. Qt 事件机制,底层实现原理

    [1]事件 事件是可以被控件识别的操作.如按下确定按钮.选择某个单选按钮或复选框. 每种控件有自己可识别的事件,如窗体的加载.单击.双击等事件,编辑框(文本框)的文本改变事件等等. 事件就是用户对窗口 ...

  7. 【转】QT事件传递与事件过滤器

         [概览] 1.重载特定事件函数.    比如: mousePressEvent(),keyPressEvent(),  paintEvent() .      2.重新实现QObject:: ...

  8. 我也来说说js的事件机制

    原文链接:http://www.w3cfuns.com/notes/17398/8062de2558ef495ce6cb7679f940ae5c.html 学js,不懂事件机制,基本可以说学了js,就 ...

  9. spring boot 源码分析(七) 事件机制 之 SpringApplicationEvent

    2019独角兽企业重金招聘Python工程师标准>>> 一.前言 前面的文章我们讲解了一下spring boot配置文件加载的相关源码分析,下面我们将从源码角度讲解一下spring  ...

最新文章

  1. 绝望,上传文件失败。。遇到并解决java.lang.NullPointerException
  2. 判断是否在数组中,若在输入其下标,否则输入-1
  3. python函数可以作为容器对象吗_正确理解Python函数是第一类对象
  4. 对互联网中常见地图的坐标系探讨
  5. spark job生成的时间驱动
  6. IntelliJ Idea学习笔记006---Idea左侧栏不显示目录结构
  7. t–sql pl–sql_SQL Server处理器性能指标–第3部分–指示硬件组件问题的指标
  8. 火狐浏览器表单不跳转_火狐浏览器的表单问题,求解_html/css_WEB-ITnose -
  9. 如何深入学习c语言,如何深入学习C语言?
  10. 由于受到新冠疫情的影响,GDP同比增长率从2019年的6.1%下滑到了2.3%
  11. Axure RP9 制作平台界面
  12. Photoshop绝色美女通道抠图法
  13. 免费内网穿透端口映射工具-网络通
  14. 基于ETH创建自己的代币
  15. 汽车降价结束会迎来报复性涨价吗
  16. Box-constrained L-BFGS 相关知识拓展
  17. 如何进行格式转化?几招帮你搞定格式转换
  18. lnmp实现搭建商城网站
  19. 2020.07 学习日记
  20. 关于libpthread.a静态链接缺少依赖问题

热门文章

  1. 北京python讲师培训- 百度
  2. 如何用python画配电系统图
  3. js 处理树形结构数据
  4. 使用自定义数据绘制脑地形矩阵图
  5. 简单搞定python进制转换
  6. ENSP华为路由器出口NAT实验
  7. 贷款行业 | 大数据精准获客 ,破除流量困局
  8. 干货丨大数据基础术语精粹来袭
  9. 层次聚类算法的原理及实现Hierarchical Clustering
  10. Jmeter 断言的使用(响应断言,json断言,断言响应时间)