When to use
You are writing QDoc comments for QML types (in .cpp/.h backing a QML type, or in .qml/.qdoc files) and want correctly linked, buildable API reference pages. Reach here when the goal is documentation output.
Not for: writing the QML itself (use qt-qml) or reviewing QML for defects and performance (use qt-qml-review).
Method
- Open each type with
\qmltype and place it in a module with \inqmlmodule. Decision point: if the QML type is backed by a C++ class, add \nativetype <Class> (Qt 6.6+; older Qt uses \instantiates) so the pages cross-link.
- Document every public property with
\qmlproperty <type> <name>. Decision point: if the property is init-only mark \readonly; if it is the type's default property mark \default.
- Document signals with
\qmlsignal, invokable methods with \qmlmethod, and attached properties with \qmlattachedproperty. Decision point: if a member exists only on an attached type, use the attached variants so it renders under the attaching type.
- Version each addition with
\since QtQuick 6.x. Decision point: if a member arrived in a later minor release than the type, put \since on the member, not the type.
- Cross-link with
\sa and inline \l. Decision point: if you reference another module's type, link the fully qualified name so QDoc resolves across modules.
- Configure the module's
.qdocconf to scan QML sources and register the module, then build with qdoc.
Example
/*!
\qmltype BackendModel
\inqmlmodule Demo
\nativetype BackendModel
\brief Holds and mutates the demo counter.
\section1 Usage
\qml
BackendModel { id: model }
Text { text: model.count }
\endqml
*/
/*!
\qmlproperty int BackendModel::count
\readonly
The current counter value. Emits \l countChanged on update.
\sa increment
*/
/*!
\qmlmethod void BackendModel::increment()
\since QtQuick 6.5
Increments \l count by one.
*/
/*!
\qmlsignal BackendModel::countChanged()
Emitted whenever \l count changes.
*/
Pitfalls
- Missing \inqmlmodule. Without it QDoc cannot place the type in a module and the page is orphaned / links break.
- Wrong backing command.
\instantiates is legacy; on Qt 6.6+ use \nativetype to link the QML type to its C++ class (and vice-versa).
- Type-and-name mismatch.
\qmlproperty needs <type> <TypeName>::<prop>; omitting the type or the qualifier breaks resolution and the property renders untyped.
- Undocumented enums. Enums exposed to QML need their own doc block with each value listed via
\value, or they render blank.
- Signal vs handler confusion. Document the signal with
\qmlsignal; QDoc auto-generates the on<Signal> handler entry — do not document the handler separately.
- qdocconf not scanning QML. If
.qml/headers aren't in the source/header dirs, QML types silently never appear.
Output format
/*!
\qmltype <TypeName>
\inqmlmodule <Module>
\nativetype <BackingClass> // if C++-backed
\since QtQuick 6.x
\brief <one line>.
<description, optionally with \qml ... \endqml or \code ... \endcode>
*/
/*!
\qmlproperty <type> <TypeName>::<prop>
\readonly // if applicable
\default // if default property
<description> \sa <related>
*/
Reference
- Core commands:
\qmltype, \qmlproperty, \qmlsignal, \qmlmethod, \qmlattachedproperty, \qmlattachedsignal — declare the documented QML members.
- Module placement:
\inqmlmodule <Module> assigns the type to its QML module; must match the URI in qt_add_qml_module.
- C++ linking:
\nativetype <Class> (Qt 6.6+) links QML type ⇄ backing C++ class; the older \instantiates <Class> command does the same on pre-6.6 and is now deprecated.
- Property syntax:
\qmlproperty <type> <TypeName>::<name> — the type and the TypeName:: qualifier are both required. Modifiers: \readonly, \default, \required.
- Enums: document an enum exposed to QML with a doc block and one
\value <Name> <desc> per enumerator; expose from C++ via Q_ENUM/QML_ELEMENT on the enclosing type.
- Versioning:
\since QtQuick 6.x (or \since <Module> 6.x) marks the introducing release; place on the member if later than the type.
- Cross-links:
\sa for "See also" lists; \l <Type> / \l {Module::Type} for inline links; \brief for the summary line.
- Code blocks:
\qml ... \endqml for QML snippets (syntax-highlighted as QML), \code ... \endcode for generic/C++ code.
- qdocconf: set
sourcedirs/headerdirs to include the QML module's sources, list the module under qhp config, and set outputdir; run qdoc <project>.qdocconf (or via qt_add_docs / qt_generate_qml_docs in CMake).
1---2name: qt-qml-docs3description: Document QML types, properties, signals, and modules with QDoc for Qt6 QML modules.4---56## When to use78You are writing QDoc comments for QML types (in `.cpp`/`.h` backing a QML type, or in `.qml`/`.qdoc` files) and want correctly linked, buildable API reference pages. Reach here when the goal is documentation output.910**Not for:** writing the QML itself (use `qt-qml`) or reviewing QML for defects and performance (use `qt-qml-review`).1112## Method13141. Open each type with `\qmltype` and place it in a module with `\inqmlmodule`. **Decision point:** if the QML type is backed by a C++ class, add `\nativetype <Class>` (Qt 6.6+; older Qt uses `\instantiates`) so the pages cross-link.152. Document every public property with `\qmlproperty <type> <name>`. **Decision point:** if the property is init-only mark `\readonly`; if it is the type's default property mark `\default`.163. Document signals with `\qmlsignal`, invokable methods with `\qmlmethod`, and attached properties with `\qmlattachedproperty`. **Decision point:** if a member exists only on an attached type, use the attached variants so it renders under the attaching type.174. Version each addition with `\since QtQuick 6.x`. **Decision point:** if a member arrived in a later minor release than the type, put `\since` on the member, not the type.185. Cross-link with `\sa` and inline `\l`. **Decision point:** if you reference another module's type, link the fully qualified name so QDoc resolves across modules.196. Configure the module's `.qdocconf` to scan QML sources and register the module, then build with `qdoc`.2021## Example2223```cpp24/*!25 \qmltype BackendModel26 \inqmlmodule Demo27 \nativetype BackendModel28 \brief Holds and mutates the demo counter.2930 \section1 Usage31 \qml32 BackendModel { id: model }33 Text { text: model.count }34 \endqml35*/3637/*!38 \qmlproperty int BackendModel::count39 \readonly40 The current counter value. Emits \l countChanged on update.41 \sa increment42*/4344/*!45 \qmlmethod void BackendModel::increment()46 \since QtQuick 6.547 Increments \l count by one.48*/4950/*!51 \qmlsignal BackendModel::countChanged()52 Emitted whenever \l count changes.53*/54```5556## Pitfalls5758- **Missing \inqmlmodule.** Without it QDoc cannot place the type in a module and the page is orphaned / links break.59- **Wrong backing command.** `\instantiates` is legacy; on Qt 6.6+ use `\nativetype` to link the QML type to its C++ class (and vice-versa).60- **Type-and-name mismatch.** `\qmlproperty` needs `<type> <TypeName>::<prop>`; omitting the type or the qualifier breaks resolution and the property renders untyped.61- **Undocumented enums.** Enums exposed to QML need their own doc block with each value listed via `\value`, or they render blank.62- **Signal vs handler confusion.** Document the signal with `\qmlsignal`; QDoc auto-generates the `on<Signal>` handler entry — do not document the handler separately.63- **qdocconf not scanning QML.** If `.qml`/headers aren't in the source/header dirs, QML types silently never appear.6465## Output format6667```68/*!69 \qmltype <TypeName>70 \inqmlmodule <Module>71 \nativetype <BackingClass> // if C++-backed72 \since QtQuick 6.x73 \brief <one line>.7475 <description, optionally with \qml ... \endqml or \code ... \endcode>76*/7778/*!79 \qmlproperty <type> <TypeName>::<prop>80 \readonly // if applicable81 \default // if default property82 <description> \sa <related>83*/84```8586## Reference8788- **Core commands:** `\qmltype`, `\qmlproperty`, `\qmlsignal`, `\qmlmethod`, `\qmlattachedproperty`, `\qmlattachedsignal` — declare the documented QML members.89- **Module placement:** `\inqmlmodule <Module>` assigns the type to its QML module; must match the URI in `qt_add_qml_module`.90- **C++ linking:** `\nativetype <Class>` (Qt 6.6+) links QML type ⇄ backing C++ class; the older `\instantiates <Class>` command does the same on pre-6.6 and is now deprecated.91- **Property syntax:** `\qmlproperty <type> <TypeName>::<name>` — the type and the `TypeName::` qualifier are both required. Modifiers: `\readonly`, `\default`, `\required`.92- **Enums:** document an enum exposed to QML with a doc block and one `\value <Name> <desc>` per enumerator; expose from C++ via `Q_ENUM`/`QML_ELEMENT` on the enclosing type.93- **Versioning:** `\since QtQuick 6.x` (or `\since <Module> 6.x`) marks the introducing release; place on the member if later than the type.94- **Cross-links:** `\sa` for "See also" lists; `\l <Type>` / `\l {Module::Type}` for inline links; `\brief` for the summary line.95- **Code blocks:** `\qml ... \endqml` for QML snippets (syntax-highlighted as QML), `\code ... \endcode` for generic/C++ code.96- **qdocconf:** set `sourcedirs`/`headerdirs` to include the QML module's sources, list the module under `qhp` config, and set `outputdir`; run `qdoc <project>.qdocconf` (or via `qt_add_docs` / `qt_generate_qml_docs` in CMake).