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

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

下面是QT经典的Hello world程序

 #include <qapplication.h>
#include <qpushbutton.h>
#include <qfont.h> int main( int argc, char **argv )
{
QApplication a( argc, argv );
QPushButton quit( "Quit", );
quit.resize( , );
quit.setFont( QFont( "Times", , QFont::Bold ) );
QObject::connect( &quit, SIGNAL(clicked()), &a, SLOT(quit()) );
quit.show();
return a.exec();
}

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

 QApplication : QCoreApplication : QObject

先观察QApplication的构造函数:

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

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

看Q_D的定义:

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

Q_D(QApplication);展开后是:

 QApplicationPrivate * const d = d_func();

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

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

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

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

 QApplicationPrivate::construct();

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

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

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

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

 QCoreApplication::QCoreApplication(QCoreApplicationPrivate &p)
: QObject(p, )
{
init();
// note: it is the subclasses' job to call
// QCoreApplicationPrivate::eventDispatcher->startingUp();
}

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

 void QCoreApplication::init()
{
Q_D(QCoreApplication); // Get the application name/instance if qWinMain() was not invoked
set_winapp_name(); // 设置应用程序的名字 Q_ASSERT_X(!self, "QCoreApplication", "there should be only one application object");
QCoreApplication::self = this; QThread::initialize(); // 初始化线程 // use the event dispatcher created by the app programmer (if any)
if (!QCoreApplicationPrivate::eventDispatcher)
QCoreApplicationPrivate::eventDispatcher = d->threadData->eventDispatcher;
// otherwise we create one
if (!QCoreApplicationPrivate::eventDispatcher)
d->createEventDispatcher(); // 生成事件分发
Q_ASSERT(QCoreApplicationPrivate::eventDispatcher != ); if (!QCoreApplicationPrivate::eventDispatcher->parent())
QCoreApplicationPrivate::eventDispatcher->moveToThread(d->threadData->thread); d->threadData->eventDispatcher = QCoreApplicationPrivate::eventDispatcher; if (!coreappdata()->app_libpaths) {
// make sure that library paths is initialized
libraryPaths(); // 确认或设定DLL库的路径
} else {
d->appendApplicationPathToLibraryPaths();
} qt_startup_hook(); // 目前是空函数
}

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关联起来

QT分析之QApplication的初始化的更多相关文章

  1. 1、QT分析之QApplication的初始化

    原文地址:http://blog.163.com/net_worm/blog/static/1277024192010097430321/ 在开始分析之前交代一下,一是分析的QT在Window平台实现 ...

  2. 2、QT分析之QPushButton的初始化

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201001003326522/ 在简单的QT程序的第二行,声明了一个QPushButto ...

  3. QT分析之QPushButton的初始化

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201001003326522/ 在简单的QT程序的第二行,声明了一个QPushButto ...

  4. Qt事件分发机制源码分析之QApplication对象构建过程

    我们在新建一个Qt GUI项目时,main函数里会生成类似下面的代码: int main(int argc, char *argv[]) { QApplication application(argc ...

  5. 10、QT分析之WebKit

    该文章整理自 网易博客 http://blog.163.com/net_worm/blog/static/12770241920101831312381/ 转载请注明出处 WebKit是QT4新整合的 ...

  6. 3、QT分析之消息事件机制

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201001432028526/ 上回我们分析到QPushButton的初始化,知道了Wi ...

  7. 5、QT分析之网络编程

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201002842553382/ 首先对Windows下的网络编程总结一下: 如果是服务器 ...

  8. QT分析之WebKit

    该文章整理自 网易博客 http://blog.163.com/net_worm/blog/static/12770241920101831312381/ 转载请注明出处 WebKit是QT4新整合的 ...

  9. QT分析之网络编程

    原文地址:http://blog.163.com/net_worm/blog/static/127702419201002842553382/ 首先对Windows下的网络编程总结一下: 如果是服务器 ...

随机推荐

  1. 动态的GRE OVER IPSEC的实验模拟与分析

    此篇博客正在介绍的是下图中的Dynamic P2P GRE OVER IPSEC VPN: 为什么出现这种动态的GRE OVER IPSEC VPN技术呢? 首先在前面几篇博客中已经介绍过了,动态是为 ...

  2. epoll 服务端 ET模式

    windows下IOCP, linux下 epoll. epoll模型其实也是一个同步模型,ET是epoll里面的一种模式,叫 边缘触发. 个人理解,类似于 windows下的事件选择模型.代码如下: ...

  3. JDBC与Java数据库编程基础

    一.JDBC 概述 1.什么是JDBC 称为Java数据库连接,它是一种用于数据库访问的应用程序API,由一组用Java语言编写的类和接口组成,有了JDBC就可以用同一的语法对多种关系数据库进行访问, ...

  4. linux如何制作程序桌面快捷方式

    1.生成通过apt或者dpkg安装的程序的桌面快捷方式 他们的快捷方式在/usr/share/applications中,比如我们要生成火狐的桌面快捷方式,执行下列命令 cp /usr/share/a ...

  5. element-ui 分页注意事项

    <template> <div id="monitor"> 一页显示 {{currentCount}}条 当前第 {{currentPage}}页 < ...

  6. #define NULL ((void *)0)引起的风波

    1. 看下宏定义的结构体 typedef struct { ]; //CMEI/IMEI ]; //server ]; //CMEI/IMEI } Options; 2. 定义的NULL #defin ...

  7. 使用vs code写php及调试

    原文来自:http://www.cnblogs.com/CLR010/p/5276077.html 首页先改下php.ini 一般是在最底部,有就修改没有就加上去下面的配置: xdebug.remot ...

  8. 一个只有十行的精简MVVM框架(下篇)

    本文来自网易云社区. 让我们来加点互动 前面学生信息的身高的单位都是默认m,如果新增一个需求,要求学生的身高的单位可以在m和cm之间切换呢? 首先需要一个变量来保存度量单位,因此这里必须用一个新的Mo ...

  9. Appium Inspector定位元素与录制简单脚本

    本次以微信为例, 使用Appium自带的Inspector定位工具定位元素, 以及进行最最最简单脚本的录制: capabilities = { "platformName": &q ...

  10. WEB页面常用基本控件测试用例

    一.树控件的测试外观操作 1)项目中的所有树是否风格一致 2)树结构的默认状态是怎样的.比如默认树是否是展开,是展开几级?  是否有默认的焦点? 默认值是什么?展开的节点图标和颜色? 2.执行操作 1 ...