Qt事件分发机制源码分析之QApplication对象构建过程
我们在新建一个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源码目录
上一篇: php根据分类合并数组的方法实例详解
下一篇: 前端变量命名规则和关键字的简单介绍