欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Qt事件分发机制源码分析之QApplication对象构建过程

程序员文章站 2023-11-02 16:05:34
Qt事件分发机制源码分析包含QApplication对象构建过程、主界面显示过程、事件循环处理过程三个主题,这三个主题就覆盖了Qt GUI交互应用程序的核心机制内容;这篇博文主要讲解第一个主题,即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对象构建过程

查看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();
}

其也没有实际性的内容。

主要集中在qapplicationprivateqguiapplicationprivateqcoreapplicationprivate类的内部处理,这也是qt一贯的用法,即信息隐藏。

其类关系图如下

Qt事件分发机制源码分析之QApplication对象构建过程

因此函数调用返回到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::initqcoreapplicationprivate::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类继承关系如下图所示

Qt事件分发机制源码分析之QApplication对象构建过程

因此,qapplication构造时创建了eventdispatcher

关于qapplication对象构建过程就讲述完毕了,后续博文会看到eventdispatcher、qwindowscontext的用途

有部分代码位于qtbase\src\plugins\platforms源码目录