Qt事件分发机制源码分析之QApplication对象构建过程
我们在新建一个Qt GUI项目时,main
函数里会生成类似下面的代码:
int main(int argc, char *argv[])
{
QApplication application(argc, argv);
CQDialog dialog(NULL);
dialog.show();
return application.exec();
}
对应的步骤解释如下
1.构建QApplication
对象
2.构建CQDialog主界面
3.主界面显示
4.QApplication
对象进入事件循环处理直至退出
上述步骤包含QApplication
对象构建过程、主界面显示过程、事件循环处理过程三个主题。
这篇博文主要讲解第一个主题,即QApplication
对象构建过程。
QApplication
类继承关系如下图所示
查看Qt源码QApplication
的构造函数
#ifdef Q_QDOC
QApplication::QApplication(int &argc, char **argv)
#else
QApplication::QApplication(int &argc, char **argv, int _internal)
#endif
: QGuiApplication(*new QApplicationPrivate(argc, argv, _internal))
{
Q_D(QApplication);
d->init();
}
QApplication
父类QGuiApplication
的构造函数
QGuiApplication::QGuiApplication(QGuiApplicationPrivate &p)
: QCoreApplication(p)
{
}
可以看到QGuiApplication
的构造函数为空内容,进入到QGuiApplication
父类QCoreApplication
的构造函数
QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
#ifdef QT_NO_QOBJECT
: d_ptr(&p)
#else
: QObject(p, 0)
#endif
{
d_func()->q_ptr = this;
// note: it is the subclasses' job to call
// QCoreApplicationPrivate::eventDispatcher->startingUp();
}
其也没有实际性的内容。
主要集中在QApplicationPrivate
、QGuiApplicationPrivate
、QCoreApplicationPrivate
类的内部处理,这也是Qt一贯的用法,即信息隐藏。
其类关系图如下
因此函数调用返回到QApplication
构造函数中,QApplicationPrivate::init
函数被调用用于初始化操作
void QApplicationPrivate::init()
{
#if defined(Q_OS_MACOS)
QMacAutoReleasePool pool;
#endif
QGuiApplicationPrivate::init();
initResources();
qt_is_gui_used = (application_type != QApplicationPrivate::Tty);
process_cmdline();
// Must be called before initialize()
qt_init(this, application_type);
initialize();
eventDispatcher->startingUp();
#ifdef QT_EVAL
extern void qt_gui_eval_init(QCoreApplicationPrivate::Type);
qt_gui_eval_init(application_type);
#endif
#ifndef QT_NO_ACCESSIBILITY
// factory for accessible interfaces for widgets shipped with Qt
QAccessible::installFactory(&qAccessibleFactory);
#endif
}
QGuiApplicationPrivate::init
会调用QCoreApplicationPrivate::init
,QCoreApplicationPrivate::init
会进行eventDispatcher的创建,如下代码所示
#ifndef QT_NO_QOBJECT
// use the event dispatcher created by the app programmer (if any)
if (!eventDispatcher)
eventDispatcher = threadData->eventDispatcher.load();
// otherwise we create one
if (!eventDispatcher)
createEventDispatcher();
Q_ASSERT(eventDispatcher);
if (!eventDispatcher->parent()) {
eventDispatcher->moveToThread(threadData->thread);
eventDispatcher->setParent(q);
}
threadData->eventDispatcher = eventDispatcher;
eventDispatcherReady();
#endif
基于多态性,QGuiApplicationPrivate::createEventDispatcher
被调用
void QGuiApplicationPrivate::createEventDispatcher()
{
Q_ASSERT(!eventDispatcher);
if (platform_integration == 0)
createPlatformIntegration();
// The platform integration should not mess with the event dispatcher
Q_ASSERT(!eventDispatcher);
eventDispatcher = platform_integration->createEventDispatcher();
}
createEventDispatcher
函数里做两件事情
1.创建平台插件(Windows、Linux)
2.根据平台插件创建eventDispatcher
以我在Windows平台上开发为例
1.创建QWindowsIntegration
以及QWindowsGuiEventDispatcher
2.在QWindowsIntegration
创建过程中会生成QWindowsContext
对象
QEventDispatcherWin32
类继承关系如下图所示
因此,QApplication
构造时创建了eventDispatcher
关于QApplication
对象构建过程就讲述完毕了,后续博文会看到eventDispatcher、QWindowsContext
的用途
有部分代码位于qtbase\src\plugins\platforms源码目录
Qt事件分发机制源码分析之QApplication对象构建过程的更多相关文章
- Android事件分发机制源码分析
Android事件分发机制源码分析 Android事件分发机制源码分析 Part1事件来源以及传递顺序 Activity分发事件源码 PhoneWindow分发事件源码 小结 Part2ViewGro ...
- Android查缺补漏(View篇)--事件分发机制源码分析
在上一篇博文中分析了事件分发的流程及规则,本篇会从源码的角度更进一步理解事件分发机制的原理,如果对事件分发规则还不太清楚的童鞋,建议先看一下上一篇博文 <Android查缺补漏(View篇)-- ...
- Android View事件分发-从源码分析
View事件分发-从源码分析 学习自 <Android开发艺术探索> https://blog.csdn.net/qian520ao/article/details/78555397?lo ...
- Android View 事件分发机制 源码解析 (上)
一直想写事件分发机制的文章,不管咋样,也得自己研究下事件分发的源码,写出心得~ 首先我们先写个简单的例子来测试View的事件转发的流程~ 1.案例 为了更好的研究View的事件转发,我们自定以一个My ...
- ApplicationEvent事件机制源码分析
<spring扩展点之三:Spring 的监听事件 ApplicationListener 和 ApplicationEvent 用法,在spring启动后做些事情> <服务网关zu ...
- Qt update刷新之源码分析(一)
在做GUI开发时,要让控件刷新,会调用update函数:那么在调用了update函数后,Qt究竟基于什么原理.执行了什么代码使得屏幕上有变化?本文就带大家来探究探究其内部源码. Qt手册中关于QWid ...
- Springboot学习04-默认错误页面加载机制源码分析
Springboot学习04-默认错误页面加载机制源码分析 前沿 希望通过本文的学习,对错误页面的加载机制有这更神的理解 正文 1-Springboot错误页面展示 2-Springboot默认错误处 ...
- Envoy 源码分析--程序启动过程
目录 Envoy 源码分析--程序启动过程 初始化 main 入口 MainCommon 初始化 服务 InstanceImpl 初始化 启动 main 启动入口 服务启动流程 LDS 服务启动流程 ...
- SpringBoot源码分析之SpringBoot的启动过程
SpringBoot源码分析之SpringBoot的启动过程 发表于 2017-04-30 | 分类于 springboot | 0 Comments | 阅读次数 SpringB ...
随机推荐
- 跑酷天堂C++小黑框版
上:跳跃 左右:行走 #include <bits/stdc++.h> #include <windows.h> #include <conio.h> using ...
- 1、Hibernate-入门
一.概述 1.什么是Hibernate: Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,h ...
- [springboot 开发单体web shop] 5. 用户登录及首页展示
用户登录及前端展示 用户登录 在之前的文章中我们实现了用户注册和验证功能,接下来我们继续实现它的登录,以及登录成功之后要在页面上显示的信息. 接下来,我们来编写代码. 实现service 在com.l ...
- 《吊打面试官》系列-Redis常见面试题(带答案)
你知道的越多,你不知道的越多 点赞再看,养成习惯 GitHub上已经开源,有面试点思维导图,欢迎[Star]和[完善] 前言 Redis在互联网技术存储方面使用如此广泛,几乎所有的后端技术面试官都要在 ...
- python入门递归之阶乘
def recurursion(n): if n == 1: return 1 else: return n * recurursion(n-1) number = int(input("请 ...
- nginx跨域解决方案
nginx跨域解决方案Access to Font at 'http://47.104.86.187/yinjiatoupiao2/iconfont/iconfont.woff' from origi ...
- redis 数据库主从不一致问题解决方案
在聊数据库与缓存一致性问题之前,先聊聊数据库主库与从库的一致性问题. 问:常见的数据库集群架构如何? 答:一主多从,主从同步,读写分离. 如上图: (1)一个主库提供写服务 (2)多个从库提供读服务 ...
- 解决mybatis中 数据库column 和 类的属性名property 不一致的两种方式
解决方式way1:resultMap (1)studentMapper.xml <!-- 当数据库的字段名 和 类的属性名 不一致的时候的解决方式:2种 way1--> <selec ...
- volatile相关内容
volatile是jvm提供的轻量级的同步机制 保证可见性(一个线程的修改对其它线程是可见的) 不保证原子性 禁止指令重排序 什么是指令重排? 计算机在执行程序时,为了提高性能,编译器和处理器会对指令 ...
- VsCode Python配置安装教程
1.软件下载地址 Python官网: https://www.python.org/downloads/windows/ Python下载地址: https://www.python.org/ftp/ ...