1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
4\page qtqml-documents-structure.html
5\title Structure of a QML Document
6\brief Description of the structure of QML documents
9A QML document is a self contained piece of QML source code that consists of three parts:
12 \li An optional list of pragmas
13 \li Its \e import statements
14 \li A single root object declaration
17By convention, a single empty line separates the imports from the object hierarchy definition.
19QML documents are always encoded in UTF-8 format.
25Pragmas are instructions to the QML engine itself that can be used to specify
26certain characteristics of objects in the current file or to modify how the
27engine interprets code. The following pragmas are exaplained in details below.
31\li \c ListPropertyAssignBehavior
32\li \c ComponentBehavior
33\li \c FunctionSignatureBehavior
34\li \c NativeMethodBehavior
35\li \c ValueTypeBehavior
41\c{pragma Singleton} declares the component defined in the QML document as
42singleton. Singletons are created only once per QML engine. In order to use
43a QML-declared singleton you also have to register it with its module. See
44\l{qt_target_qml_sources} for how to do this with CMake.
46\section2 ListPropertyAssignBehavior
48With this pragma you can define how assignments to list properties shall be
49handled in components defined in the QML document. By default, assigning to a
50list property appends to the list. You can explicitly request this behavior
51using the value \c{Append}. Alternatively, you can request the contents of list
52properties to always be replaced using \c{Replace}, or replaced if the property
53is not the default property using \c{ReplaceIfNotDefault}. For example:
56pragma ListPropertyAssignBehavior: ReplaceIfNotDefault
59\note The same declaration can also be given for C++-defined types, by adding
60the \l{QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_APPEND},
61\l{QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE}, and
62\l{QML_LIST_PROPERTY_ASSIGN_BEHAVIOR_REPLACE_IF_NOT_DEFAULT} macros to the
65\section2 ComponentBehavior
67You may have multiple components defined in the same QML file. The root
68scope of the QML file is a component, and you may additionally have
69elements of type \l QQmlComponent, explicitly or implicitly created
70as properties, or inline components. Those components are nested. Each
71of the inner components is within one specific outer component. Most of
72the time, IDs defined in an outer component are accessible within all
73its nested inner components. You can, however, create elements from a
74component in any a different context, with different IDs available.
75Doing so breaks the assumption that outer IDs are available. Therefore,
76the engine and the QML tooling cannot generally know in advance what
77type, if any, such IDs will resolve to at run time.
79With the ComponentBehavior pragma you can restrict all inner components
80defined in a file to only create objects within their original context.
81If a component is bound to its context, you can safely use IDs from
82outer components in the same file within the component. QML tooling will
83then assume the outer IDs with their specific types to be available.
85In order to bind the components to their context specify the \c{Bound}
89pragma ComponentBehavior: Bound
92This implies that, in case of name clashes, IDs defined outside a bound
93component override local properties of objects created from the
94component. Otherwise it wouldn't actually be safe to use the IDs since
95later versions of a module might add more properties to the component.
96If the component is not bound, local properties override IDs defined
97outside the component, but not IDs defined inside the component.
99The example below prints the \e r property of the ListView object with
100the id \e color, not the \e r property of the rectangle's color.
103pragma ComponentBehavior: Bound
111 delegate: Rectangle {
112 Component.onCompleted: console.log(color.r)
117The default value of \c ComponentBehavior is \c{Unbound}. You can also
118specify it explicitly. In a future version of Qt the default will change
121Delegate components bound to their context don't receive their own
122private contexts on instantiation. This means that model data can only
123be passed via \l{Required Properties}{required properties} in this case.
124Passing model data via context properties will not work. This concerns
125delegates to e.g. \l{Instantiator}, \l{Repeater}, \l{ListView},
126\l{TableView}, \l{GridView}, \l{TreeView} and in general anything that
127uses \l{DelegateModel} internally.
129For example, the following will \e{not} work:
132pragma ComponentBehavior: Bound
136 delegate: Rectangle {
142The \c{delegate} property of \l{ListView} is a component. Therefore, a
143\l{Component} is implicitly created around the \l{Rectangle} here. That
144component is bound to its context. It doesn't receive the context property
145\c{model} provided by \l{ListView}. To make it work, you'd have to write
149pragma ComponentBehavior: Bound
153 delegate: Rectangle {
154 required property color myColor
160You can nest components in a QML file. The pragma holds for all components in
161the file, no matter how deeply nested.
163\section2 FunctionSignatureBehavior
165With this pragma you can change the way type annotations on functions
166are handled. Since Qt 6.7 type annotations are enforced when calling
167functions. Before, only the \l{QML script compiler} enforced the type
168annotations. The interpreter and JIT compiler ignored them. Always
169enforcing the type annotations is a behavior change in comparison to
170earlier versions since you could call functions with mismatched
173Specifying \c{Ignored} as value makes the QML engine and the
174\l{QML script compiler} ignore any type annotations and therefore
175restores the pre-6.7 behavior of the interpreter and JIT. As a result
176less code is compiled to C++ ahead of time, and more code has to be
177interpreted or JIT-compiled.
179Specifying \c{Enforced} as value explicitly states the default: Type
180annotations are always enforced.
182\sa {Type annotations and assertions}
184\section2 NativeMethodBehavior
186Calling C++ methods with \c this objects different from the one they were
187retrieved from is broken, due to historical reasons. The original object is
188used as \c this object. You can allow the given \c this object to be used by
189setting \c {pragma NativeMethodBehavior: AcceptThisObject}. Specifying
190\c RejectThisObject keeps the historical behavior.
192An example of this can be found under \l {C++ methods and the 'this' object}.
194\section2 ValueTypeBehavior
196With this pragma you can change the way value types and sequences are handled.
198Usually lower case names cannot be type names in JavaScript code. This is a
199problem because value type names are lower case. You can specify \c{Addressable}
200as value for this pragma to change this. If \c{Addressable} is specified a
201JavaScript value can be explicitly coerced to a specific, named, value type. This is
202done using the \c as operator, like you would do with object types. Furthermore,
203you can also check for value types using the \c instanceof operator:
206pragma ValueTypeBehavior: Addressable
211 property real b: (a as rect).x
212 property bool c: a instanceof rect
214 property var rect // inaccessible. "rect" is a type name.
218If the type does not match, casting returns \c undefined. \c instanceof
219only checks for inheritance, not for all possible type coercions. So, for
220example, a \l{QRect} is not a \c rect value type since \c rect is \l{QRectF}
221in C++, and therefore not related by inheritance. With \c as you can cast
222to any type compatible via coercion.
224Since \c rect in the above example is now a type name, it will shadow any
225properties called \c{rect}.
227Explicitly casting to the desired type helps tooling. It can allow the
228\l{Qt Quick Compiler} generate efficient code where it otherwise would not be
229able to. You can use \l{qmllint Reference}{qmllint} to find such occurrences.
231There is also a \c{Inaddressable} value you can use to explicitly specify the
234Value types and sequences are generally treated as references. This means, if
235you retrieve a value type instance from a property into a local value, and then
236change the local value, the original property is also changed. Furthermore,
237if you write the original property explicitly, the local value is also updated.
238This behavior is rather unintuitive in many places, and you should not rely on
239it. The \c{Copy} and \c{Reference} values for the \c{ValueTypeBehavior} pragma
240are experimental options to change this behavior. You should not use them.
241Specifying \c{Copy} causes all value types to be treated as actual copies.
242Specifying \c{Reference} explicitly states the default behavior.
244Rather than using \c{Copy} you should explicitly re-load references to value
245types and sequences any time they can have been affected by side effects. Side
246effects can happen whenever you call a function or imperatively set a property.
247\l qmllint provides guidance on this. For example, in the following code
248the variable \c f is affected by side effects after writing \c width. This is
249because there may be a binding in a derived type or in a \c Binding element
250that updates \c font when \c width is changed.
255 function a() : real {
263In order to address this, you can avoid holding \c f across the write operation
269 function a() : real {
278This, in turn can be shortened to:
283 function a() : real {
284 width = font.pixelSize;
285 return font.pointSize;
290You might assume that re-retrieving the \c font property is costly, but actually
291the QML engine automatically refreshes value type references each time you read
292from them. So this is not more expensive than the first version, but a clearer
293way to express the same operations.
295\sa {Type annotations and assertions}
299With this pragma you can set the context for the translations in the file.
302pragma Translator: myTranslationContext
306pragma Translator: "myTranslationContext"
309For more information on internationalization with QML, see \l{QML: Use qsTr()}{Use qsTr}.
313A document must import the necessary modules or type namespaces to enable the
314engine to load the QML object types referenced within the document. By default,
315a document can access any QML object types that have been defined through
316\c .qml files in the same directory; if a document needs to refer to any other
317object types, it must import the type namespace into which those types have
320QML does \e not have a preprocessor that modifies the document prior to
321presentation to the \l{QQmlEngine}{QML engine}, unlike C or C++.
322The \c import statements do not copy and prepend the code in the document, but
323instead instruct the QML engine on how to resolve type references found
324in the document. Any type reference present in a QML document - such as \c
325Rectangle and \c ListView - including those made within a \l {JavaScript
326Expressions in QML Documents}{JavaScript block} or \l {Property Binding}{property
327bindings}, are \e resolved based exclusively on the import statements. At least
328one \c import statement must be present such as \c{import QtQuick 2.0}.
330Please see the \l{qtqml-syntax-imports.html}{QML Syntax - Import Statements}
331documentation for in-depth information about QML imports.
334\section1 The Root Object Declaration
336A QML document describes a hierarchy of objects which can be instantiated.
337Each object definition has a certain structure; it has a type, it can have an
338id and an object name, it can have properties, it can have methods, it can have
339signals and it can have signal handlers.
341A QML file must only contain \b {a single root object definition}. The following is invalid and will generate an error:
347Rectangle { width: 200; height: 200; color: "red" }
348Rectangle { width: 200; height: 200; color: "blue" } // invalid!
351This is because a .qml file automatically defines a QML type, which encapsulates a \e single QML object definition. This is discussed further in \l{qtqml-documents-definetypes.html}{Documents as QML object type definitions}.