原文地址:http://blog.163.com/net_worm/blog/static/1277024192010097430321/

在开始分析之前交代一下,一是分析的QT在Window平台实现(其它OS类似);二、分析的手段为看源码+单步跟踪。有时候会让编译器产生预编译后的输出(使用-E参数),便于观察;三、分析得QT版本为4.5.3

下面是QT经典的Hello world程序

 1 #include <qapplication.h>
 2 #include <qpushbutton.h>
 3 #include <qfont.h>
 4
 5 int main( int argc, char **argv )
 6 {
 7  QApplication a( argc, argv );
 8  QPushButton quit( "Quit", 0 );
 9  quit.resize( 75, 30 );
10  quit.setFont( QFont( "Times", 18, QFont::Bold ) );
11  QObject::connect( &quit, SIGNAL(clicked()), &a, SLOT(quit()) );
12  quit.show();
13  return a.exec();
14 }

第一句声明了一个QApplication的对象,QApplication的类继承关系为:

1 QApplication : QCoreApplication : QObject

先观察QApplication的构造函数:

1 QApplication::QApplication(int &argc, char **argv)
2     : QCoreApplication(*new QApplicationPrivate(argc, argv, GuiClient))
3 { Q_D(QApplication); d->construct(); }

这里先后做了三件事:新生成一个QApplicationPrivate对象并传递给QCoreApplication;宏Q_D;调用d->construct()。

看Q_D的定义:

1 #define Q_D(Class) Class##Private * const d = d_func()

Q_D(QApplication);展开后是:

1 QApplicationPrivate * const d = d_func();

在附近正好看到Q_Q的定义:

1 #define Q_Q(Class) Class * const q = q_func()

由此看到在QT的程序里最好不要定义d、q这样的变量。

所以d->construct()调用的其实是

1 QApplicationPrivate::construct();

那么这个construct()干了什么事呢?

 1 void QApplicationPrivate::construct()
 2 {
 3     initResources();          // 初始化资源
 4
 5     qt_is_gui_used = (qt_appType != QApplication::Tty);
 6     process_cmdline();     // 扫描分析命令行参数
 7     // Must be called before initialize()
 8     qt_init(  this, qt_appType  );  // 在initialize()之前必须执行的初始化,例如色彩、字体、键盘等
 9     initialize();
10     eventDispatcher->startingUp();
11
12 }

其中eventDispatcher->startingUp();实际调用的是:QEventDispatcherWin32::startingUp(),主要是注册事件分发器。

回来看QCoreApplication的构造过程,把QApplicationPrivate对象传递给QOjbec,然后调用init()。

1 QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
2     : QObject(p, 0)
3 {
4     init();
5     // note: it is the subclasses' job to call
6     // QCoreApplicationPrivate::eventDispatcher->startingUp();
7 }

我们先来看QCoreApplication::init()干了什么事呢?

 1 void QCoreApplication::init()
 2 {
 3     Q_D(QCoreApplication);
 4
 5     // Get the application name/instance if qWinMain() was not invoked
 6     set_winapp_name();  // 设置应用程序的名字
 7
 8     Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");
 9     QCoreApplication::self = this;
10
11     QThread::initialize();  // 初始化线程
12
13     // use the event dispatcher created by the app programmer (if any)
14     if (!QCoreApplicationPrivate::eventDispatcher)
15         QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher;
16     // otherwise we create one
17     if (!QCoreApplicationPrivate::eventDispatcher)
18         d->createEventDispatcher();  // 生成事件分发
19     Q_ASSERT(QCoreApplicationPrivate::eventDispatcher != 0);
20
21     if (!QCoreApplicationPrivate::eventDispatcher->parent())
22         QCoreApplicationPrivate::eventDispatcher->moveToThread(d->threadData->thread);
23
24     d->threadData->eventDispatcher = QCoreApplicationPrivate::eventDispatcher;
25
26     if (!coreappdata()->app_libpaths) {
27         // make sure that library paths is initialized
28         libraryPaths();  // 确认或设定DLL库的路径
29     } else {
30         d->appendApplicationPathToLibraryPaths();
31     }
32
33     qt_startup_hook();  // 目前是空函数
34 }

Object的构造又做了什么事情呢?

QObject::QObject(QObjectPrivate &dd, QObject *parent)     : d_ptr(&dd) 将QApplicationPrivate对象传递给d_ptr,这个d_ptr是什么呢?

我们看QObject的类定义,d_ptr是QObject中唯一的数据成员:

protected:     QObjectData *d_ptr; 至此,QApplication对象的初始基本分析完毕,除了很多初始化的动作之外,主要就是把QApplication和QApplicationPrivate关联起来

转载于:https://www.cnblogs.com/lfsblack/p/5278987.html

QT分析之QApplication的初始化相关推荐

  1. qt中新增html,Qt和HTML笔记:初始化

    为了应对最近的比赛,但对很对 GUI 系统都不怎么熟悉,而且又要用 C++ 进行项目核心代码的编辑.RetVal 希望团队做出一个很炫的图形界面,不过,对 C++ 的窗口系统还真的不熟悉.于是尝试用 ...

  2. Android10.0 日志系统分析(二)-logd、logcat架构分析及日志系统初始化-[Android取经之路]

    摘要:本节主要来讲解Android10.0 日志系统的架构分析,以及logd.logcat的初始化操作 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级 ...

  3. 【spring源码分析】IOC容器初始化(二)

    前言:在[spring源码分析]IOC容器初始化(一)文末中已经提出loadBeanDefinitions(DefaultListableBeanFactory)的重要性,本文将以此为切入点继续分析. ...

  4. 《深入理解Spark:核心思想与源码分析》——SparkContext的初始化(叔篇)——TaskScheduler的启动...

    <深入理解Spark:核心思想与源码分析>一书前言的内容请看链接<深入理解SPARK:核心思想与源码分析>一书正式出版上市 <深入理解Spark:核心思想与源码分析> ...

  5. k8s replicaset controller源码分析(1)- 初始化与启动分析

    replicaset controller分析 replicaset controller简介 replicaset controller是kube-controller-manager组件中众多控制 ...

  6. ORBSLAM源码理论分析2—单目初始化

    ORBSLAM源码理论分析2-单目初始化 1.构造初始化帧1 2.第一次初始化 3.构造初始化帧2 4.F1与F2特征匹配 5.初始化解算位姿 5.1.计算单应矩阵 5.2.计算基础矩阵 5.3.评估 ...

  7. 【FRR 】【BGP协议分析】 1 - BGP 初始化

    FRR支持BGP-4,BGP-4+协议,BGP协议本身的知识点,可以参考很多资料,TCP/IP路由技术是一本不错的书,建议多看几次,还有红茶哥的博客和视频 http://blog.sina.com.c ...

  8. Zookeeper源码分析:Follower角色初始化

    参考资料 <<从PAXOS到ZOOKEEPER分布式一致性原理与实践>> zookeeper-3.0.0 Follower角色初始化 本文主要简述一下Follower角色初始化 ...

  9. Zookeeper源码分析:Leader角色初始化

    参考资料 <<从PAXOS到ZOOKEEPER分布式一致性原理与实践>> zookeeper-3.0.0 Leader角色初始化 在上文的选举完成之后,每个zk实例都会根据选举 ...

  10. android6.0源码分析之Runtime的初始化

    Android运行时作为android架构的一部分,起着非常重要的作用,它和核心库(Core Libraries)组成了Android运行时库层.本文将依据android源码对AndroidRunti ...

最新文章

  1. Waymo自动驾驶详解
  2. 成功解决使用jupyter notebook命令打开原先存的.ipynb文件突然消失的问题
  3. php 斗鱼人数,斗鱼旭旭宝宝再度登顶指数榜首位 单日弹幕人数高达48万人
  4. 英文Ubantu系统安装中文输入法
  5. Objective-C中的@property
  6. 贪心算法之用优先队列(priority_queue)实现哈夫曼编码问题
  7. Kubernetes 也有局限性吗?
  8. [Azure] 使用 Visual Studio 2013 管理中国版 Azure 订阅
  9. CCF认证历年试题解(python版本 + c语言版+c++版本)
  10. sql server 按年月日分组
  11. NER中的词汇增强方法(LatticeLSTM、CGN、FLAT、Simple-Lexicon)
  12. 神经元细胞分布全身吗,人体神经细胞分布图
  13. 2021年全国程序员工资出炉想要年薪60万,难吗?网友,扎心了
  14. apple music导入本地歌曲及歌词
  15. [益智]:平面上有 2N + 1 个点,其中无三点共线,也无四点共圆,是否一定存在三个点,经过这三点作一个圆,使得圆内点数等于园外点数?
  16. 函数部分编程大作业(持续更新)
  17. nvcc: command not found
  18. 数据仓库 pdf 电子书大全
  19. STM32F0xx定时器输出PWM配置
  20. IE8允许ActiveX控件设置

热门文章

  1. 数据库学习笔记2-隔离等级 isolation level
  2. 设计模式之GOF23享元模式
  3. 数据库的表连接和函数学习
  4. 多关键字排序的c语言编程,常见排序——“计数排序(三关键字)”的源程序(C语言版)...
  5. Spring IOC三种注入方式(接口注入、setter注入、构造器注入)
  6. Oracle 临时表、数据闪回、系统常用表、及常用操作
  7. Spring boot 自定义拦截器 获取 自定义注解 信息
  8. java 区间api_Java 常用API(一)
  9. hdu6715 算术 2019百度之星初赛3-1003
  10. 仅当使用了列列表并且 IDENTITY_INSERT 为 ON 时,才能为表't_ArticleFiles'中的标识列指定显式值。...