zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    C++实现网格水印之调试笔记(六)—— 提取完成
    C++实现网格水印之调试笔记(五)—— 提取出错
    C++实现网格水印之调试笔记(四)—— 完成嵌入
    Spark ---RDD
    Running Spark on YARN
    Spark官方2 ---------Spark 编程指南(1.5.0)
    Spark官方1 ---------Spark SQL和DataFrame指南(1.5.0)
    spark与hive的集成
    [mysql] ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES).
    HDFS概述(6)————用户手册
  • 原文地址:https://www.cnblogs.com/liushui-sky/p/6474046.html
Copyright © 2011-2022 走看看