1、QT分析之QApplication的初始化
原文地址: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关联起来.
转自:http://www.cnblogs.com/lfsblack/p/5278987.html
1、QT分析之QApplication的初始化的更多相关文章
- QT分析之QApplication的初始化
原文地址:http://blog.163.com/net_worm/blog/static/1277024192010097430321/ 在开始分析之前交代一下,一是分析的QT在Window平台实现 ...
- 2、QT分析之QPushButton的初始化
原文地址:http://blog.163.com/net_worm/blog/static/127702419201001003326522/ 在简单的QT程序的第二行,声明了一个QPushButto ...
- QT分析之QPushButton的初始化
原文地址:http://blog.163.com/net_worm/blog/static/127702419201001003326522/ 在简单的QT程序的第二行,声明了一个QPushButto ...
- Qt事件分发机制源码分析之QApplication对象构建过程
我们在新建一个Qt GUI项目时,main函数里会生成类似下面的代码: int main(int argc, char *argv[]) { QApplication application(argc ...
- 10、QT分析之WebKit
该文章整理自 网易博客 http://blog.163.com/net_worm/blog/static/12770241920101831312381/ 转载请注明出处 WebKit是QT4新整合的 ...
- 3、QT分析之消息事件机制
原文地址:http://blog.163.com/net_worm/blog/static/127702419201001432028526/ 上回我们分析到QPushButton的初始化,知道了Wi ...
- 5、QT分析之网络编程
原文地址:http://blog.163.com/net_worm/blog/static/127702419201002842553382/ 首先对Windows下的网络编程总结一下: 如果是服务器 ...
- QT分析之WebKit
该文章整理自 网易博客 http://blog.163.com/net_worm/blog/static/12770241920101831312381/ 转载请注明出处 WebKit是QT4新整合的 ...
- QT分析之网络编程
原文地址:http://blog.163.com/net_worm/blog/static/127702419201002842553382/ 首先对Windows下的网络编程总结一下: 如果是服务器 ...
随机推荐
- tips: javascript 参数传递含有空格怎么办?
js 方法传参有时候会遇到空格,空格会报错,因为它会默认空格后是元素 解决方法就是使用 escape 和 unescape html: var title = escape(rowObject.tit ...
- 一个里表世界切换的shader效果
之前GGJ实现了一个,但是实现方式上有很多冗余.今天正好在做一个类似的东西,重新做了一个版本 还是当时美术画的素材: 由于里表世界是不同的内容,是两张材质.所以拆分成不同Layer之后,里世界单独渲染 ...
- iOS 基础-----关于UIView 的 frame 与 bounds
首先,对于frame 大家都很熟悉,是当前view ,相对于其父视图view 的坐标,例如: UIView *view1 = [[UIView alloc] initWithFrame:CGRectM ...
- 虚拟机vmware如何进入bios设置,设置启动项(装系统时用)
方法/步骤 1 打开你要进入Bios的虚拟系统界面(处于关机状态).我这里的是server2003. 2 鼠标点击上部的 虚拟机 菜单. 3 在弹出的菜单中鼠标点击 电源 . 4 在弹出的下一级菜 ...
- 事件,委托,action与func文章不错的
https://www.cnblogs.com/yinqixin/p/5056307.html https://www.cnblogs.com/BLoodMaster/archive/2010/07/ ...
- windows 内存管理的几种方式及其优缺点
windows 内存管理方式主要分为:页式管理,段式管理,段页式管理. 页式管理的基本原理是将各进程的虚拟空间划分为若干个长度相等的页:页式管理把内存空间按照页的大小划分成片或者页面,然后把页式虚拟地 ...
- MySQL开发索引创建规范
1. [强制]业务上具有唯一特性的字段,即使是多个字段的组合,也必须建成唯一索引. 说明:不要以为唯一索引影响了insert速度,这个速度损耗可以忽略,但提高查找速度是明显的:另外,即使在应用层做了非 ...
- mysql创建唯一索引
查看索引 show index from 数据库表名 alter table 数据库add index 索引名称(数据库字段名称) PRIMARY KEY(主键索引) ALTER TABLE `ta ...
- 玩转Bootstrap(JS插件篇)-第1章 模态弹出框 :1-3 模态弹出框
模态弹出框(Modals) 这一小节我们先来讲解一个“模态弹出框”,插件的源文件:modal.js. 右侧代码编辑器(30行)就是单独引入 bootstrap 中发布出的“modal.js”文件. 样 ...
- vue2.0如何自定义全局变量的方法
方法一:http://www.jianshu.com/p/04dffe7a6b74 //在mian.js中写入函数 Vue.prototype.changeData = function (){ al ...