我們在新建一個Qt GUI專案時,main函式里會生成類似下面的代碼:
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物件進入事件回圈處理直至退出
上述步驟包含QApplication物件構建程序、主界面顯示程序、事件回圈處理程序三個主題,
這篇博文主要講解第一個主題,即QApplication物件構建程序,
QApplication類繼承關系如下圖所示

查看Qt原始碼QApplication的建構式
#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的建構式
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();
}
其也沒有實際性的內容,
主要集中在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原始碼目錄
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/82041.html
標籤:C++
上一篇:北華大學網路賽題
下一篇:各種排序(二)
