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 生成 HTMLQObject class reference 页面。
本手册介绍了如何在 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 时,单次执行模式才可用,而您在编写模块文档并将文档与其他 Qt 模块集成时会经常使用单次执行模式。
要在单一执行模式下运行 QDoc,请在命令行中添加-single-exec
,并向 QDoc 传递一个主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 编译系统并不使用 QDoc 的单一执行模式来生成 Qt5 文档。它以标准模式运行 QDoc。之所以采用标准模式,是因为这是转换 Qt4 QDoc 以处理 Qt5 中 Qt 模块化的最简单方法。在 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 会解析模块的所有源文件,然后使用这些信息生成模块的索引文件。它被称为准备阶段,因为它准备模块的索引文件。模块的第二次 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。不过,可能需要对主 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 会调用outputformats
变量指定的输出生成器,将文档格式化并写入配置文件中outputdir变量指定的目录。
命令类型
QDoc 可解释三种类型的命令:
主题命令可识别您正在文档化的元素,例如 C++ 类、函数、类型或没有映射到底层 C++ 元素的额外文本页。
上下文命令告诉 QDoc 正在文档化的元素与其他文档化元素的关系,例如,下一页和上一页链接、包含在页面组中或库模块中。上下文命令还可以提供 QDoc 无法从源文件中获取的有关被记录元素的信息,例如,该元素是否线程安全、是否是重载或重新实现的函数,或者是否已被废弃。
标记命令告诉 QDoc 应如何渲染文档中的文本和图像元素,或文档的大纲结构。
© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.