![]() |
Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
|
The Qt Bridge project will need to generate some files in the build folder for qmllint and qmlls to find and understand the QML types defined by that Qt Bridge project. For each QML Module defined by the project, files like qmldir, qmltypes, resources files etc should be generated in the build folder.
Tooling like qmlls or qmllint, just like the QML runtime, detect folders with a qmldir file as QML Modules. The qmldir format is described here. The location of the folder with the qmldir should be in the import path and should follow the URI. For example, module MyModule and org.com.mycompany should have their respective qmldir files at /path/to/importpath/MyModule/qmldir and /path/to/importpath/org/com/mycompany/qmldir. The other files of the QML Modules, like qml files, qmltypes, and so on, should be in the same folder as the qmldir.
TLDR: the qmldir needs at least
The qmldir file refers to a .qmltypes file via a typeinfo directive. The qmldir and qmltypes file are usually in the same folder. The .qmltypes file describes types usable in QML but not defined via a QML file, for example a QML type from a bridges project. You can generate .qmltypes files with qmltyperegistrar from JSON.
qmltyperegistrar is the tool that generates the .qmltypes files for the tooling. It requires multiple arguments:
See MOC's JSON output on what information qmltyperegistrar requires to generate .qmltypes file.
Note that qmltyperegistrar also has a mode to generate C++ QML type registration code, which is not needed in a Qt Bridge project.
Resource files files end in .qrc and follow the XML format. Qmllint and qmlls use resource files to map source files to build folders. Each QML Module generates three .qrc files, described in the following subsections.
Note that the QML tooling does not actively try to use the resource file system.
C++ CMake projects generate this resource file at /path/to/build/.qt/rcc/X_raw_qml_0.qrc, where X stands for the CMake target name of the QML Module.
The .qrc file mapping from the qrc path to the source QML file looks like:
where:
The /qt/qml/ qrc file system prefix matters for the QML runtime, but not for the QML tooling.
C++ CMake projects generate this resource file at /path/to/build/.qt/rcc/qmake_X.qrc, where X stands for the QML Module URI.
The .qrc file mapping from the qrc path to the build qmldir file looks like:
where:
The LSP client is responsible for passing the relevant information to qmlls. The easiest way to do it in Qt 6.10 is to write a .qmlls.build.ini file in the build folder and to call qmlls binary with the -B /path/to/buildfolder argument.
qmlls from 6.10.0 reads the .qmlls.build.ini file from the build folder to figure out import paths, documentation paths, etc. The .qmlls.build.ini file is expected to be in /path/to/build/.qt/.qmlls.build.ini, where /path/to/build is the path passed to qmlls via the LSP client.
The .qmlls.build.ini file starts with a [General] section. That section contains the documentation directory:
where /path/to/qt/ is the path to the Qt installation.
Each QML Module has its own section in the .qmlls.build.ini file. Each section is named after the path to the source folder of the QML Module, with slashes (/) escaped with <SLASH>. In C++ the source folder of a QML Module would be the folder where the CMakeLists.txt with the qt_add_qml_module(...) call definining the QML Module is located. Each section has a key importPaths that describes the import paths to use for QML files of the current module. On windows, ; separates the different import paths. Linux and macOS use : instead. For example, the QML Module at /tmp/untitled would have the section
Note that importPaths contains the import paths of:
The CMake build system calls qmllint in the C++/CMake world.
To call qmllint without CMake, pass import paths as described before in the .qmlls.build.ini part via the -I option. To pass multiple import paths, use -I multiple times. In addition to the imports path specified this way, qmllint will use its own default import path, the current directory, and all qmldir found inside the current directory. To disable the automatic adding of import paths, use the --bare option.
Then, pass the resource files (.qrc files) to qmllint via the --resource commandline option. Qmllint reads the resource files to correctly map QML files from their build path to their source paths. The content of the .qrc files is described earlier in the resource file section.
User --bare to avoid adding the default import path, and the current directory and auto-imports any qmldir found in the current directory.
Next, pass --bare and the file to be linted to qmllint. --bare ensures that only the import paths passed on the commandline are used for the linting.
A qmllint invokation on a Main.qml file, which is in the MyModule QML module and depends on a QML module located in /path/to/build/ would look like
for example.
This section describes how to generate the JSON required by qmltyperegistrar for the .qmltypes files.
The root element of the JSON is a list, like
for example.
where:
The classes list contains objects like:
The next subsections explain what each field should contain in detail.
classInfos describes how a type should be registered in the QML type system and is a list of objects of the form:
In a C++ CMake project, the classInfos are set via C++'s QML_* macros. Here is a "translation" table from C++ macro to class info object:
| corresponding C++ macro | name(s) (as string) | value(s) |
|---|---|---|
| QML_ELEMENT | QML.Element | "auto" |
| QML_NAMED_ELEMENT("name") | QML.Element | "name" |
| QML_ANONYMOUS | QML.Element | "anonymous" |
| QML_UNCREATABLE("reason...") | QML.Creatable, QML.UncreatableReason | "false", "reason..." |
| QML_VALUE_TYPE("name") | QML.Element | "name" |
| QML_CONSTRUCTIBLE_VALUE | QML.Creatable, QML.CreationMethod | "true", "construct" |
| QML_STRUCTURED_VALUE | QML.Creatable, QML.CreationMethod | "true", "structured" |
| QML_SINGLETON | QML.Singleton | "true" |
| QML_ADDED_IN_VERSION(x,y) | QML.AddedInVersion | QString::number(QTypeRevision::fromVersion(x, y).toEncodedVersion()) |
| QML_EXTRA_VERSION(x,y) | QML.ExtraVersion | QString::number(QTypeRevision::fromVersion(x, y).toEncodedVersion()) |
| QML_REMOVED_IN_VERSION(X,Y) | QML.RemovedInVersion | QString::number(QTypeRevision::fromVersion(x, y).toEncodedVersion()) |
| QML_ATTACHED(attachedType) | QML.Attached | attachedType's name |
| QML_EXTENDED(extendedType) | QML.Extended | extendedType's name |
| QML_EXTENDED_NAMESPACE(extendedNamespace) | QML.Extended, QML.ExtensionIsNamespace | extendedNamespace's name, "true" |
| QML_NAMESPACE_EXTENDED(extendedNamespace) | QML.Extended | extendedNamespace's name |
| QML_SEQUENTIAL_CONTAINER(valueType) | QML.Sequence | valueType's name |
| QML_FOREIGN(foreignType) | QML.Foreign | foreignType's name |
| QML_UNAVAILABLE | QML.Foreign | "QQmlTypeNotAvailable" |
| QML_FOREIGN_NAMESPACE(foreignNamespace) | QML.Foreign, QML.ForeignIsNamespace | foreignNamespace's name, "true" |
| QML_CUSTOMPARSER | QML.HasCustomParser | "true" |
| QML_USING(originalType) | QML.Using | originalType's name |
className is the name of the class. In the C++ world, this is the name of the C++ class that contains the QML_ELEMENT macro, like
for example.
className is the fully-qualified name of the class. In the C++ world, this is the name of the C++ class that contains the QML_ELEMENT macro, like
for example.
The line number where this Class is defined. Qmlls uses this information for "go to definition" from QML to the Qt Bridge language, for example
Properties contain a list of properties with following fields:
| Property field | Description | Type |
|---|---|---|
| bindable | name of the QBindable<T> member | boolean |
| constant | true for constant properties | boolean |
| final | true for final properties | boolean |
| index | index of the property in the QMetaObject | int |
| lineNumber | the line number where this property is defined | int |
| member | name of the member accessor | string |
| name | name of the property | string |
| notify | name of the change signal | string |
| privateClass | name of the private class | string |
| read | name of the getter | string |
| required | true for required properties | boolean |
| reset | name of the reset method | string |
| revision | revision of the property | int, obtained via QTypeRevision::toEncodedVersion() |
| type | name of the type of the property | string |
| write | name of the setter | string |
Some field names correspond to the arguments of Q_PROPERTY, see its documentation here.
For example:
Enums contain a list of enums with following fields:
| Enum field | Description | Type |
|---|---|---|
| alias | alternative name of the enum | string |
| isClass | true for enums defined with enum class ... in C++ | boolean |
| isFlag | true for QFlags | boolean |
| lineNumber | line number where this enum is defined | int |
| name | name of the enum | string |
| type | type of the enum | string |
| values | list of enum values | list<string> |
For example:
The field methods contains a list of methods with following fields:
| Method field | Description | Type |
|---|---|---|
| access | method access, can be public, protected, or private | string |
| arguments | method argument names and types | list of objects with name and type string fields |
| index | index of the method in the QMetaObject | int |
| isCloned | true when this method is cloned (e.g. overloads) | boolean |
| isConstructor | true for JS constructors | boolean |
| isConst | true for const methods | boolean |
| isJavaScriptFunction | true for variable argument functions in JS | boolean |
| lineNumber | line number where this method is defined | int |
| name | name of the method | string |
| returnType | type of the return value | string |
| revision | revision of the method | int, obtained via QTypeRevision::toEncodedVersion() |
For example:
Note that for isCloned, in C++, the following code:
generates two methods: one with one argument, and one without arguments to support the default argument. This might require some care when interacting with Qt Bridge languages that support default parameters.
The field signals contains a list of signals. Signals have the same fields as methods, like
for example.
The field slots contains a list of slots. Slots have the same fields as methods, like
for example.
The field constructors contains a list of JS constructors. JS constructors can be called from JS with the JS new operator, not to be confused with C++ or the Qt Bridge language constructor. JS constructors have the same fields as methods, like
for example.
True when type is an object, false when it is a gadget or namespace, like
for example.
True when type is a gadget, false when it is an object or namespace, like
for example.
True when exposing a namespace, false for objects or gadgets, like
for example.
The field superClasses contains a list with one base type with following fields:
| Base type field | Description | Type |
|---|---|---|
| access | access modifier, can be public, protected, or private | string |
| name | name of the base type | string |
like
for example.
Note that multiple super classes are currently not supported, use the interfaces field as a substitute for multiple inheritance.
The field interfaces contains a list of interface names this type implements, like
for example.
In C++, this is written by the Q_INTERFACES or QML_IMPLEMENTS_INTERFACES macros.