咱们在新建一个Qt GUI项目时,main
函数里会生成相似下面的代码:app
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
对象进入事件循环处理直至退出ui
上述步骤包含QApplication
对象构建过程、主界面显示过程、事件循环处理过程三个主题。this
这篇博文主要讲解第一个主题,即QApplication
对象构建过程。spa
QApplication
类继承关系以下图所示插件
查看Qt源码QApplication
的构造函数code
#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
的构造函数orm
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(); }
其也没有实际性的内容。blog
主要集中在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源码目录