Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
structure.qdoc
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3/*!
4\page qtqml-documents-structure.html
5\title Structure of a QML Document
6\brief Description of the structure of QML documents
7
8
9A QML document is a self contained piece of QML source code that consists of three parts:
10
11 \list
12 \li An optional list of pragmas
13 \li Its \e import statements
14 \li A single root object declaration
15 \endlist
16
17By convention, a single empty line separates the imports from the object hierarchy definition.
18
19QML documents are always encoded in UTF-8 format.
20
21
22
23\section1 Pragmas
24
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.
28
29\list
30\li \c Singleton
31\li \c ListPropertyAssignBehavior
32\li \c ComponentBehavior
33\li \c FunctionSignatureBehavior
34\li \c NativeMethodBehavior
35\li \c ValueTypeBehavior
36\li \c Translator
37\endlist
38
39\section2 Singleton
40
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.
45
46\section2 ListPropertyAssignBehavior
47
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:
54
55\qml
56pragma ListPropertyAssignBehavior: ReplaceIfNotDefault
57\endqml
58
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
63class declaration.
64
65\section2 ComponentBehavior
66
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.
78
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.
84
85In order to bind the components to their context specify the \c{Bound}
86argument:
87
88\qml
89pragma ComponentBehavior: Bound
90\endqml
91
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.
98
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.
101
102\qml
103pragma ComponentBehavior: Bound
104import QtQuick
105
106ListView {
107 id: color
108 property int r: 12
109 model: 1
110
111 delegate: Rectangle {
112 Component.onCompleted: console.log(color.r)
113 }
114}
115\endqml
116
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
119to \c{Bound}.
120
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.
128
129For example, the following will \e{not} work:
130
131\qml
132pragma ComponentBehavior: Bound
133import QtQuick
134
135ListView {
136 delegate: Rectangle {
137 color: model.myColor
138 }
139}
140\endqml
141
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
146it this way:
147
148\qml
149pragma ComponentBehavior: Bound
150import QtQuick
151
152ListView {
153 delegate: Rectangle {
154 required property color myColor
155 color: myColor
156 }
157}
158\endqml
159
160You can nest components in a QML file. The pragma holds for all components in
161the file, no matter how deeply nested.
162
163\section2 FunctionSignatureBehavior
164
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
171arguments before.
172
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.
178
179Specifying \c{Enforced} as value explicitly states the default: Type
180annotations are always enforced.
181
182\sa {Type annotations and assertions}
183
184\section2 NativeMethodBehavior
185
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.
191
192An example of this can be found under \l {C++ methods and the 'this' object}.
193
194\section2 ValueTypeBehavior
195
196With this pragma you can change the way value types and sequences are handled.
197
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:
204
205\qml
206pragma ValueTypeBehavior: Addressable
207import QtQml
208
209QtObject {
210 property var a
211 property real b: (a as rect).x
212 property bool c: a instanceof rect
213
214 property var rect // inaccessible. "rect" is a type name.
215}
216\endqml
217
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.
223
224Since \c rect in the above example is now a type name, it will shadow any
225properties called \c{rect}.
226
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.
230
231There is also a \c{Inaddressable} value you can use to explicitly specify the
232default behavior.
233
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.
243
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.
251
252\qml
253import QtQuick
254Text {
255 function a() : real {
256 var f = font;
257 width = f.pixelSize;
258 return f.pointSize;
259 }
260}
261\endqml
262
263In order to address this, you can avoid holding \c f across the write operation
264on \c width:
265
266\qml
267import QtQuick
268Text {
269 function a() : real {
270 var f = font;
271 width = f.pixelSize;
272 f = font;
273 return f.pointSize;
274 }
275}
276\endqml
277
278This, in turn can be shortened to:
279
280\qml
281import QtQuick
282Text {
283 function a() : real {
284 width = font.pixelSize;
285 return font.pointSize;
286 }
287}
288\endqml
289
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.
294
295\sa {Type annotations and assertions}
296
297\section2 Translator
298
299With this pragma you can set the context for the translations in the file.
300
301\qml
302pragma Translator: myTranslationContext
303\endqml
304
305\qml
306pragma Translator: "myTranslationContext"
307\endqml
308
309For more information on internationalization with QML, see \l{QML: Use qsTr()}{Use qsTr}.
310
311\section1 Imports
312
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
318been registered.
319
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}.
329
330Please see the \l{qtqml-syntax-imports.html}{QML Syntax - Import Statements}
331documentation for in-depth information about QML imports.
332
333
334\section1 The Root Object Declaration
335
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.
340
341A QML file must only contain \b {a single root object definition}. The following is invalid and will generate an error:
342
343\code
344// MyQmlFile.qml
345import QtQuick 2.0
346
347Rectangle { width: 200; height: 200; color: "red" }
348Rectangle { width: 200; height: 200; color: "blue" } // invalid!
349\endcode
350
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}.
352
353*/