咱們在新建一個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源碼目錄