QDoc 简介

QDoc 是 Qt 开发者用来生成软件项目文档的工具。它通过从项目源文件中提取 QDoc 注释,然后将这些注释格式化为 HTML 页面或 DocBook XML 文档来实现。QDoc 在 .cpp 文件和 .qdoc 文件中查找 QDoc 注释。QDoc 不会在 .h 文件中查找 QDoc 注释。QDoc 注释始终以感叹号 (!) 开头)。例如

/*!
    \class QObject
    \brief The QObject class is the base class of all Qt objects.

    \ingroup objectmodel

    \reentrant

    QObject is the heart of the Qt \l{Object Model}. The
    central feature in this model is a very powerful mechanism
    for seamless object communication called \l{signals and
    slots}. You can connect a signal to a slot with connect()
    and destroy the connection with disconnect(). To avoid
    never ending notification loops you can temporarily block
    signals with blockSignals(). The protected functions
    connectNotify() and disconnectNotify() make it possible to
    track connections.

    QObjects organize themselves in \l {Object Trees &
    Ownership} {object trees}. When you create a QObject with
    another object as parent, the object will automatically
    add itself to the parent's \c children() list. The parent
    takes ownership of the object. It will automatically
    delete its children in its destructor. You can look for an
    object by name and optionally type using findChild() or
    findChildren().

    Every object has an objectName() and its class name can be
    found via the corresponding metaObject() (see
    QMetaObject::className()). You can determine whether the
    object's class inherits another class in the QObject
    inheritance hierarchy by using the \c inherits() function.

....
*/

从上面的 QDoc 注释中,QDoc 生成了 QObject 类参考 页面。

本手册解释了如何在 QDoc 注释中使用 QDoc 命令将优秀的文档嵌入到您的源文件中。它还解释了如何创建一个 QDoc 配置文件,您将通过命令行将其传递给 QDoc。

运行 QDoc

QDoc 程序的名称为 qdoc。要从命令行运行 QDoc,给出配置文件的名称

$ ../../bin/qdoc ./config.qdocconf

QDoc 识别 .qdocconf 后缀为 QDoc 配置文件。配置文件是您告诉 QDoc 在哪里找到项目源文件、头文件和 .qdoc 文件的地方。它还告诉 QDoc 要生成哪种类型的输出(HTML、DocBook XML……)以及将生成的文档放在哪里。配置文件还包含其他 QDoc 信息的说明。

请参阅 QDoc 配置文件 了解如何设置 QDoc 配置文件的说明。

以单次执行模式运行 QDoc

从 Qt 5.5 开始,提供了一种新的运行 QDoc 的方法,该方法可以将生成 Qt5 文档所需的时间缩短多达 90%。新的 QDoc 运行方法是 单次执行 模式。由于 Qt5 构建系统仍然使用 标准 模式,因此当前单次执行模式不可用。单次执行模式仅在您自己运行 QDoc 时才可用,您通常需要经常运行 qdoc 以便记录模块并将文档与其他 Qt 模块集成。

要以单次执行模式运行 QDoc,请在命令行中添加 -single-exec 并传递给 QDoc 一个主 qdocconf 文件。这个主 qdocconf 文件仅仅是所有 Qt5 模块的 qdocconf 文件的路径列表。例如

/Users/me/qt5/qtbase/bin/qdoc -outputdir /Users/me/qt5/qtbase/doc -installdir /Users/me/qt5/qtbase/doc /Users/me/qt5/master.qdocconf -single-exec

qdocconf 文件,master.qdocconf,仅列出要处理的 Qt5 模块的所有 qdocconf 文件

/Users/me/qt5/qtbase/src/corelib/doc/qtcore.qdocconf
/Users/me/qt5/qtbase/src/network/doc/qtnetwork.qdocconf
/Users/me/qt5/qtbase/src/sql/doc/qtsql.qdocconf
/Users/me/qt5/qtbase/src/xml/doc/qtxml.qdocconf
/Users/me/qt5/qtbase/src/testlib/doc/qttestlib.qdocconf
/Users/me/qt5/qtbase/src/concurrent/doc/qtconcurrent.qdocconf
/Users/me/qt5/qtbase/src/gui/doc/qtgui.qdocconf
/Users/me/qt5/qtbase/src/platformheaders/doc/qtplatformheaders.qdocconf
/Users/me/qt5/qtbase/src/widgets/doc/qtwidgets.qdocconf
/Users/me/qt5/qtbase/src/opengl/doc/qtopengl.qdocconf
/Users/me/qt5/qtbase/src/printsupport/doc/qtprintsupport.qdocconf
/Users/me/qt5/qtbase/src/tools/qdoc/doc/config/qdoc.qdocconf
/Users/me/qt5/qtbase/qmake/doc/qmake.qdocconf
/Users/me/qt5/qtsvg/src/svg/doc/qtsvg.qdocconf
/Users/me/qt5/qtxmlpatterns/src/xmlpatterns/doc/qtxmlpatterns.qdocconf
/Users/me/qt5/qtdeclarative/src/qml/doc/qtqml.qdocconf
/Users/me/qt5/qtdeclarative/src/quick/doc/qtquick.qdocconf
/Users/me/qt5/qtquickcontrols/src/controls/doc/qtquickcontrols.qdocconf
/Users/me/qt5/qtquickcontrols/src/layouts/doc/qtquicklayouts.qdocconf
/Users/me/qt5/qtquickcontrols/src/dialogs/doc/qtquickdialogs.qdocconf
/Users/me/qt5/qtmultimedia/src/multimedia/doc/qtmultimedia.qdocconf
/Users/me/qt5/qtmultimedia/src/multimediawidgets/doc/qtmultimediawidgets.qdocconf
/Users/me/qt5/qtactiveqt/src/activeqt/doc/activeqt.qdocconf
/Users/me/qt5/qtsensors/src/sensors/doc/qtsensors.qdocconf
/Users/me/qt5/qtwebkit/Source/qtwebkit.qdocconf
/Users/me/qt5/qttools/src/assistant/help/doc/qthelp.qdocconf
/Users/me/qt5/qttools/src/assistant/assistant/doc/qtassistant.qdocconf
/Users/me/qt5/qttools/src/designer/src/uitools/doc/qtuitools.qdocconf
/Users/me/qt5/qttools/src/designer/src/designer/doc/qtdesigner.qdocconf
/Users/me/qt5/qttools/src/linguist/linguist/doc/qtlinguist.qdocconf
/Users/me/qt5/qtwebkit-examples/doc/qtwebkitexamples.qdocconf
/Users/me/qt5/qtgraphicaleffects/src/effects/doc/qtgraphicaleffects.qdocconf
/Users/me/qt5/qtscript/src/script/doc/qtscript.qdocconf
/Users/me/qt5/qtscript/src/scripttools/doc/qtscripttools.qdocconf
/Users/me/qt5/qtserialport/src/serialport/doc/qtserialport.qdocconf
/Users/me/qt5/qtdoc/doc/config/qtdoc.qdocconf

为什么标准模式运行缓慢

目前,Qt5的构建系统生成Qt5文档时,不使用QDoc的单次执行模式。它采用标准模式运行QDoc。标准模式的出现是因为这是将Qt4的QDoc转换为处理Qt5模块化的最简单方法。在Qt4中,QDoc仅遍历所有Qt4源文件一次,生成Qt的HTML文档。在生成Qt文档的过程中,Qt4 QDoc也会为Qt生成一个索引文件。这个索引文件原本打算用作输入,让后续的QDoc运行为基于Qt的其他软件库/产品生成HTML文档。Qt索引文件允许QDoc将这些其他库/产品的文档链接到Qt4文档中。

当Qt5问世之后,Qt被划分为模块。从那时起,Qt中已经添加了许多新的模块。截至5.5版本,Qt5中已有超过40个独立的模块,每个模块都有自己的文档,这些文档与其他Qt模块的文档链接(依赖)。

标准模式下,QDoc为每个模块运行两次。第一次运行用于特定Qt模块,会解析该模块的所有源文件,然后使用这些信息生成模块的索引文件。这被称为准备阶段,因为它为模块的索引文件做了准备。模块的第二次QDoc运行也会解析该模块的所有源文件,然后生成该模块的文档页面。这被称为生成阶段,因为它生成了模块的文档。

模块的文档可能会包含指向其他一个或多个Qt模块文档的HTML链接。例如,大多数Qt5模块中都包含了指向QtCore文档的链接。当一个Qt模块包含指向其他Qt模块文档的链接时,我们称该模块依赖于这些其他Qt模块。因此,当QDoc运行该模块的生成阶段时,它也必须加载这些模块的索引文件,以便可以创建这些链接。

因此,在Qt构建系统生成Qt文档时,它首先运行QDoc为每个模块执行一次,进行准备阶段以生成所有索引文件。然后,它运行QDoc为每个模块执行一次,执行生成阶段,其中它使用依赖的索引文件来生成模块的文档,包括它找到的任何跨模块链接。每次QDoc的执行,无论是准备阶段还是生成阶段,都会解析包含在模块中的所有源文件,在生成阶段还会解析依赖模块的索引文件。QDoc的运行之间没有保留或可保留的内容。

为什么单次执行模式要快得多

正如其名,单次执行模式使用单个QDoc进程来生成所有Qt5文档。单个QDoc进程仍为每个模块执行准备阶段生成阶段,但也有一些不同之处。它首先读取主qdocconf文件。然后,它读取主列表中的每个qdocconf文件,并为每个模块执行准备阶段。在准备阶段中,为模块解析所有源文件以构建模块的语法树。随后生成模块的索引文件,尽管在生成阶段QDoc不会重新读取索引文件。这里的重要区别是,在生成索引文件后,模块的语法树会被保留,所以在所有模块的准备阶段运行之后,QDoc仍然保留了它构建的所有语法树。

然后QDoc再次为每个模块执行生成阶段。但现在QDoc不需要重新解析每个模块的源文件,因为模块的语法树仍然在内存中。同样,QDoc也不需要重新读取依赖模块的索引文件,因为它仍然在内存中保留了这些模块的语法树。剩下的只是在每个模块的语法树中遍历以生成文档页面。

因此,QDoc 只对每个源文件进行一次处理,而不需要读取索引文件。这就是单次执行模式比标准模式快得多的原因。预计 Qt 构建系统最终将以单次执行模式运行 QDoc。然而,可能需要修改 master qdocconf 文件,因此上述运行 QDoc 单次执行模式的方法可能需要进行更改,请关注相关更新。

QDoc 的工作原理

QDoc 首先读取命令行中指定的配置文件。它将配置文件中的所有变量存储起来以供今后使用。它首先使用的一个变量是 outputformats。这个变量告知 QDoc 将运行哪些输出生成器。默认值是 HTML,所以如果你在配置文件中没有设置 outputformats,QDoc 将生成 HTML 输出。通常这就是你想要的,但你也可以指定 DocBook 来获取 DocBook 输出。

接下来,QDoc 使用 headerdirs 变量和/或 headers 变量的值来查找并解析你项目的所有头文件。QDoc 不会扫描头文件中的 QDoc 注释。它通过解析头文件来构建一个所有要文档化的项目的总树,换句话说,就是 QDoc 应该找到的带有 QDoc 注释的项目。

解析完所有头文件并构建了要文档化的项目的总树后,QDoc 使用 sourcedirs 变量和/或 sources 变量的值来查找并解析你项目的所有 .cpp.qdoc 文件。这些是 QDoc 要扫描的带有 QDoc 注释 的文件。请记住,QDoc 注释以感叹号开始:/*!

QDoc 对每个找到的 QDoc 注释,在总树中搜索该文档归属的项目。然后它解释注释中的 QDoc 命令,并将解释后的命令和注释文本存储在该项目的树节点中。

最后,QDoc 遍历总树。对于每个节点,如果节点存储了文档,QDoc 将调用由 outputformats 变量指定的输出生成器,以配置文件中指定的目录(在 outputdir 变量中指定)格式化和写入文档。

命令类型

QDoc 解析三种类型的命令

主题命令标识你正在文档化的元素,例如 C++ 类、函数、类型,或者不映射到底层 C++ 元素的一页额外文本。

上下文命令告知 QDoc 被文档化的元素与其他被文档化的元素之间的关系,例如,下一页和上一页链接、包含在页面组中或库模块中。上下文命令还可以提供 QDoc 无法从源文件中获得的信息,例如,元素是否线程安全,它是一个重载或重写的函数,或者它已被弃用。

标记命令告知 QDoc 如何渲染文档中的文本和图像元素,或者关于文档的大纲结构。

© 2024 Qt公司有限公司。本文件中的文档贡献属于各自的权利所有者。本提供的文档依据自由软件基金会发布的、在GNU自由文档许可证第1.3版的条款进行许可。Qt及其相关标志为芬兰以及全球其他国家的Qt公司有限公司的商标。所有其他商标均属于各自的权利所有者。