Einführung in QDoc

QDoc ist ein Werkzeug, das von Qt-Entwicklern verwendet wird, um Dokumentation für Softwareprojekte zu erstellen. Es extrahiert QDoc-Kommentare aus Projekt-Quelldateien und formatiert diese Kommentare dann als HTML-Seiten oder DocBook XML-Dokumente. QDoc findet QDoc-Kommentare in .cpp Dateien und in .qdoc Dateien. QDoc sucht nicht nach QDoc-Kommentaren in .h Dateien. Ein QDoc-Kommentar beginnt immer mit einem Ausrufezeichen (!)). Ein Beispiel:

/*!
    \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.

....
*/

Aus dem obigen QDoc-Kommentar erzeugt QDoc die HTML-Seite QObject class reference.

Dieses Handbuch erklärt, wie Sie die QDoc-Befehle in QDoc-Kommentaren verwenden, um gute Dokumentation in Ihre Quelldateien einzubetten. Es wird auch erklärt, wie Sie eine QDoc-Konfigurationsdatei erstellen, die Sie QDoc auf der Kommandozeile übergeben.

QDoc starten

Der Name des QDoc-Programms ist qdoc. Um QDoc von der Kommandozeile aus zu starten, geben Sie ihm den Namen einer Konfigurationsdatei:

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

QDoc erkennt das Suffix .qdocconf als eine QDoc-Konfigurationsdatei. In der Konfigurationsdatei teilen Sie QDoc mit, wo die Projekt-Quelldateien, Header-Dateien und .qdoc Dateien zu finden sind. Hier teilen Sie QDoc auch mit, welche Art von Ausgabe erzeugt werden soll (HTML, DocBook XML...) und wo die erzeugte Dokumentation abgelegt werden soll. Die Konfigurationsdatei enthält auch andere Informationen für QDoc.

Siehe Die QDoc-Konfigurationsdatei für eine Anleitung, wie man eine QDoc-Konfigurationsdatei einrichtet.

Ausführen von QDoc im Einzelausführungsmodus

Ab Qt 5.5 gibt es eine neue Möglichkeit, QDoc auszuführen, die die Zeit, die für die Erstellung der Qt5-Dokumentation benötigt wird, um bis zu 90% reduziert. Die neue Art, QDoc auszuführen, ist der Einzelausführungsmodus. Der Einzelausführungsmodus ist derzeit nicht im Qt5-Build-System verfügbar, das weiterhin den Standardmodus verwendet. Der Einzelausführungsmodus ist nur verfügbar, wenn Sie QDoc selbst ausführen, was Sie häufig tun werden, wenn Sie Ihr Modul dokumentieren und Ihre Dokumentation in die anderen Qt-Module integrieren.

Um QDoc im Einzelausführungsmodus zu starten, fügen Sie -single-exec zur Befehlszeile hinzu und übergeben Sie QDoc eine Master-Datei qdocconf, die einfach eine Liste von Dateipfaden für qdocconf-Dateien aller Qt5-Module ist. Ein Beispiel:

/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

Die qdocconf Datei, master.qdocconf, listet einfach die qdocconf Dateien für alle zu verarbeitenden Qt5 Module auf:

/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

Warum der Standardmodus langsam ist

Derzeit verwendet das Qt5-Build-System nicht den Einzelausführungsmodus von QDoc, um die Qt5-Dokumentation zu erzeugen. Es führt QDoc im Standardmodus aus. Der Standardmodus wurde eingeführt, weil es der einfachste Weg war, QDoc aus Qt4 zu konvertieren, um die Modularisierung von Qt in Qt5 zu bewältigen. In Qt4 lief QDoc einmal über alle Qt4-Quellen, um die HTML-Dokumentation für Qt zu erzeugen. Während der Generierung der Qt-Dokumentation erzeugte Qt4 QDoc auch eine Indexdatei für Qt. Diese Indexdatei sollte als Input für nachfolgende QDoc-Läufe verwendet werden, um HTML-Dokumentation für andere Software-Bibliotheken/Produkte zu erzeugen, die auf Qt basieren. Die Qt-Indexdatei ermöglichte es QDoc, die für diese anderen Bibliotheken/Produkte geschriebene Dokumentation mit der Qt4-Dokumentation zu verknüpfen.

Als Qt5 aufkam, wurde Qt in Module unterteilt. Seitdem sind viele neue Module zu Qt hinzugefügt worden. Ab Version 5.5 gibt es über 40 separate Module in Qt5, jedes mit seiner eigenen Dokumentation, die auf die Dokumentation anderer Qt-Module verweist (und davon abhängt).

Im Standardmodus wird QDoc zweimal für jedes Modul ausgeführt. Der erste QDoc-Lauf für ein bestimmtes Qt-Modul analysiert alle Quelldateien des Moduls und verwendet dann die Informationen, um die Indexdatei des Moduls zu erzeugen. Er wird Vorbereitungsphase genannt, weil er die Indexdatei des Moduls vorbereitet. Der zweite QDoc-Lauf für das Modul analysiert ebenfalls alle Quelldateien des Moduls und erzeugt dann die Dokumentationsseiten des Moduls. Diese Phase wird als Generierungsphase bezeichnet, da sie die Dokumentation des Moduls erzeugt.

Die Dokumentation des Moduls wird wahrscheinlich HTML-Links zu der Dokumentation eines oder mehrerer anderer Qt-Module enthalten. Zum Beispiel enthalten die meisten Qt5-Module Links zur Dokumentation in QtCore. Wenn ein Qt-Modul Links auf die Dokumentation anderer Qt-Module enthält, wird gesagt, dass dieses Modul von diesen anderen Qt-Modulen abhängt. Wenn QDoc die Generierungsphase für dieses Modul ausführt, muss es daher auch die Indexdateien für diese Module laden, damit es diese Links erstellen kann.

Wenn das Qt-Build-System die Qt-Dokumentation generiert, wird QDoc daher zunächst einmal für jedes Modul ausgeführt, um die Vorbereitungsphase durchzuführen und alle Indexdateien zu generieren. Dann führt es QDoc einmal für jedes Modul aus, um die Generierungsphase durchzuführen, in der es die abhängigen Indexdateien verwendet, um die Dokumentation des Moduls zu generieren, einschließlich aller gefundenen modulübergreifenden Links. Bei jeder Ausführung von QDoc, sowohl in der Vorbereitungsphase als auch in der Generierungsphase, werden alle Quelldateien analysiert, die im Modul enthalten sind, und in der Generierungsphase werden auch die Indexdateien für die abhängigen Module analysiert. Nichts wird zwischen den QDoc-Läufen gespeichert oder kann gespeichert werden.

Warum der Einzelausführungsmodus viel schneller ist

Wie der Name schon sagt, verwendet der Einzelausführungsmodus einen einzigen QDoc-Prozess, um die gesamte Qt5-Dokumentation zu erzeugen. Der einzelne QDoc-Prozess führt immer noch eine Vorbereitungsphase für jedes Modul und dann eine Generierungsphase für jedes Modul durch, aber es gibt ein paar Unterschiede. Er beginnt mit dem Lesen der Master-qdocconf-Datei. Dann liest er jede qdocconf-Datei in der Masterliste und führt die Vorbereitungsphase für jedes Modul durch. Während der Vorbereitungsphase werden alle Quelldateien des Moduls geparst, um einen Syntaxbaum für das Modul zu erstellen. Anschließend wird die Indexdatei des Moduls erzeugt, obwohl QDoc die Indexdateien in der Generierungsphase nicht erneut einliest. Der wichtige Unterschied besteht darin, dass der Syntaxbaum des Moduls nach der Erzeugung der Indexdatei erhalten bleibt, so dass QDoc nach der Vorbereitungsphase für alle Module noch über alle Syntaxbäume verfügt, die es aufgebaut hat.

QDoc verarbeitet dann jedes Modul erneut für die Generierungsphase. Aber jetzt muss QDoc die Quelldateien jedes Moduls nicht erneut parsen, da der Syntaxbaum des Moduls noch im Speicher ist. Ebenso wenig muss QDoc die Indexdateien für die abhängigen Module neu einlesen, da es die Syntaxbäume für diese Module noch im Speicher hat. Es bleibt nur noch, den Syntaxbaum jedes Moduls zu durchlaufen, um die Dokumentationsseiten zu erzeugen.

Daher analysiert QDoc jede Quelldatei nur ein einziges Mal und braucht keine Indexdateien zu lesen. Das macht den Einzelausführungsmodus viel schneller als den Standardmodus. Es wird erwartet, dass das Qt-Build-System QDoc irgendwann im Einzelausführungsmodus ausführen wird. Allerdings könnten Änderungen an der master qdocconf Datei erforderlich sein, so dass sich die oben beschriebene Methode, QDoc im Einzelausführungsmodus auszuführen, möglicherweise ändern muss, siehe Updates an dieser Stelle.

Wie QDoc funktioniert

QDoc beginnt mit dem Lesen der Konfigurationsdatei, die Sie in der Kommandozeile angegeben haben. Es speichert alle Variablen aus der Konfigurationsdatei für die spätere Verwendung. Eine der ersten Variablen, die verwendet wird, ist outputformats. Diese Variable teilt QDoc mit, welche Ausgabegeneratoren es ausführen soll. Der Standardwert ist HTML, d.h. wenn Sie outputformats in Ihrer Konfigurationsdatei nicht setzen, wird QDoc HTML-Ausgaben erzeugen. Das ist normalerweise das, was Sie sowieso wollen, aber Sie können auch DocBook angeben, um stattdessen eine DocBook-Ausgabe zu erhalten.

Als nächstes verwendet QDoc die Werte der Variablen headerdirs und/oder der Variablen headers, um alle Header-Dateien für Ihr Projekt zu finden und zu analysieren. QDoc durchsucht die Header-Dateien nicht nach QDoc-Kommentaren. Es analysiert die Header-Dateien, um einen Master-Tree mit allen Elementen zu erstellen, die dokumentiert werden sollen, mit anderen Worten, die Elemente, für die QDoc QDoc-Kommentare finden soll.

Nachdem alle Header-Dateien analysiert und der Master-Tree der zu dokumentierenden Elemente erstellt wurde, verwendet QDoc den Wert der sourcedirs-Variable und/oder den Wert der sources-Variable, um alle .cpp und .qdoc Dateien für Ihr Projekt zu finden und zu analysieren. Dies sind die Dateien, die QDoc nach QDoc-Kommentaren durchsucht. Denken Sie daran, dass ein QDoc-Kommentar mit einem Ausrufezeichen beginnt: /*!.

Für jeden gefundenen QDoc-Kommentar sucht QDoc im Masterbaum nach dem Element, zu dem die Dokumentation gehört. Dann interpretiert es die QDoc-Befehle in dem Kommentar und speichert die interpretierten Befehle und den Kommentartext in dem Baumknoten für das Element.

Schließlich durchläuft QDoc den Master Tree. Für jeden Knoten, wenn dieser eine Dokumentation gespeichert hat, ruft QDoc den durch die Variable outputformats spezifizierten Ausgabegenerator auf, um die Dokumentation zu formatieren und in das in der Konfigurationsdatei in der Variable outputdir angegebene Verzeichnis zu schreiben.

Befehlsarten

QDoc interpretiert drei Arten von Kommandos:

Topic Commands identifizieren das Element, das Sie dokumentieren, z.B. eine C++ Klasse, eine Funktion, einen Typ oder eine zusätzliche Textseite, die nicht auf ein zugrunde liegendes C++ Element abgebildet ist.

Kontextbefehle teilen QDoc mit, wie sich das dokumentierte Element zu anderen dokumentierten Elementen verhält, z.B. Links zur nächsten und vorherigen Seite, Einbeziehung in Seitengruppen oder Bibliotheksmodule. Kontextbefehle können auch Informationen über das dokumentierte Element liefern, die QDoc nicht aus den Quelldateien entnehmen kann, z.B. ob das Element thread-safe ist, ob es sich um eine überladene oder reimplementierte Funktion handelt oder ob es veraltet ist.

Markup-Befehle teilen QDoc mit, wie Text- und Bildelemente im Dokument gerendert werden sollen, oder wie die Gliederungsstruktur des Dokuments aussieht.

© 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.