Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
macros.qdoc
Go to the documentation of this file.
1// Copyright (C) 2025 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3
4/*!
5 \headerfile <qqmlintegration.h>
6 \inmodule QtQml
7 \inheaderfile QtQmlIntegration/qqmlintegration.h
8 \keyword qqmlintegration.h
9 \keyword QML Type Registration Macros
10
11 This header provides macros that can be used to register C++ types with QML.
12
13 \sa qt_generate_foreign_qml_types, {Overview - QML and C++ Integration}, qmltyperegistrar
14*/
15
16/*!
17 \macro QML_ELEMENT
18 \relates <qqmlintegration.h>
19
20 Declares the enclosing type or namespace to be available in QML, using its
21 class or namespace name as the QML element name.
22
23 For example, this makes the C++ class \c Slider available as a QML type
24 named \c Slider. All its properties, invokable methods and enums are exposed.
25
26 \code
27 class Slider : public QObject
28 {
29 Q_OBJECT
30 QML_ELEMENT
31 Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged FINAL)
32 // ...
33 public:
34 enum Slippiness {
35 Dry, Wet, Icy
36 };
37 Q_ENUM(Slippiness)
38
39 Q_INVOKABLE void slide(Slippiness slippiness);
40
41 // ...
42 }
43 \endcode
44
45 You can use the build system to register the type in the type namespace
46 \e {com.mycompany.qmlcomponents} with major version \c 1.
47 For qmake, specify the following in your project file:
48
49 \badcode
50 CONFIG += qmltypes
51 QML_IMPORT_NAME = com.mycompany.qmlcomponents
52 QML_IMPORT_MAJOR_VERSION = 1
53 \endcode
54
55 With CMake, you pass the URI and version to qt_add_qml_module
56
57 \badcode
58 qt6_add_qml_module(myapp
59 URI com.mycompany.qmlcomponents
60 VERSION 1.0
61 )
62 \endcode
63
64 Once registered, the type can be used in QML by importing the
65 same type namespace and version number:
66
67 \qml
68 import com.mycompany.qmlcomponents 1.0
69
70 Slider {
71 value: 12
72 Component.onCompleted: slide(Slider.Icy)
73
74 // ...
75 }
76 \endqml
77
78 You can also make namespaces tagged with Q_NAMESPACE available this way, in
79 order to expose any enums tagged with Q_ENUM_NS they contain:
80
81 \code
82 namespace MyNamespace {
83 Q_NAMESPACE
84 QML_ELEMENT
85
86 enum MyEnum {
87 Key1,
88 Key2,
89 };
90 Q_ENUM_NS(MyEnum)
91 }
92 \endcode
93
94 In QML, you can then use the enums:
95
96 \qml
97 Component.onCompleted: console.log(MyNamespace.Key2)
98 \endqml
99
100 \b{NOTE:} When classes have the same name but are located in different namespaces using
101 \l QML_ELEMENT on both of them will cause a conflict.
102 Make sure to use \l QML_NAMED_ELEMENT() for one of them instead.
103
104 \include {qualified-class-name.qdocinc} {class name must be qualified}
105
106 \sa {Choosing the Correct Integration Method Between C++ and QML}, QML_NAMED_ELEMENT(),
107 Q_REVISION(), QML_ADDED_IN_VERSION()
108*/
109
110/*!
111 \macro QML_NAMED_ELEMENT(name)
112 \relates <qqmlintegration.h>
113
114 Declares the enclosing type or namespace to be available in QML, using \a name
115 as the element name. Otherwise behaves the same as QML_ELEMENT.
116
117 \code
118 class SqlEventDatabase : public QObject
119 {
120 Q_OBJECT
121 QML_NAMED_ELEMENT(EventDatabase)
122
123 // ...
124 };
125 \endcode
126
127 \sa {Choosing the Correct Integration Method Between C++ and QML}, QML_ELEMENT
128*/
129
130/*!
131 \macro QML_ANONYMOUS
132 \relates <qqmlintegration.h>
133
134 Declares the enclosing type to be available, but anonymous in QML. The type
135 cannot be created or used to declare properties in QML, but when passed from
136 C++, it is recognized. In QML, you can use properties of this type if they
137 are declared in C++.
138
139 \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), QML_INTERFACE
140*/
141
142/*!
143 \macro QML_INTERFACE
144 \relates <qqmlintegration.h>
145
146 This macro registers the enclosing C++ type in the QML system as an interface.
147
148 Types registered as an interface in QML should also declare themselves as an
149 interface with the \l {The Meta-Object System}{meta object system}. For
150 example:
151
152 \code
153 struct FooInterface
154 {
155 QML_INTERFACE
156 public:
157 virtual ~FooInterface();
158 virtual void doSomething() = 0;
159 };
160
161 Q_DECLARE_INTERFACE(FooInterface, "org.foo.FooInterface")
162 \endcode
163
164 When registered with QML in this way, they can be used as property types:
165
166 Q_PROPERTY(FooInterface *foo READ foo WRITE setFoo)
167
168 When you assign a \l QObject sub-class to this property, the QML engine does
169 the interface cast to \c FooInterface* automatically.
170
171 Interface types are implicitly anonymous and uncreatable in QML.
172
173 \b{NOTE:} When inheriting from types using QML_INTERFACE, use \l QML_IMPLEMENTS_INTERFACES
174 instead of \l Q_INTERFACES.
175
176 \sa QML_IMPLEMENTS_INTERFACES(), QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), QML_ANONYMOUS
177*/
178
179/*!
180 \macro QML_IMPLEMENTS_INTERFACES(interfaces)
181 \relates <qqmlintegration.h>
182
183 This macro tells Qt which QML \a interfaces the class implements.
184 This macro should only be used for interfacing with classes using \l QML_INTERFACE, use \l Q_INTERFACES otherwise.
185 It's required in order for declarative registration via \l QML_ELEMENT to
186 function properly.
187
188 \sa QML_INTERFACE, Q_INTERFACES
189*/
190
191/*!
192 \macro QML_UNCREATABLE(reason)
193 \relates <qqmlintegration.h>
194
195 Declares that the enclosing type shall not be creatable from QML. This takes
196 effect if the type is available in QML, by having a \l QML_ELEMENT or
197 \l QML_NAMED_ELEMENT() macro. The \a reason will be emitted as error message if an
198 attempt to create the type from QML is detected.
199
200 Some QML types are implicitly uncreatable, in particular types exposed with
201 \l QML_ANONYMOUS or namespaces exposed with \l QML_ELEMENT or
202 \l QML_NAMED_ELEMENT().
203
204 If the type is a singleton declared with \l QML_SINGLETON, adding QML_UNCREATABLE
205 signals a promise that an instance of the type will be set on the engine
206 explicitly by using \l{QQmlEngine::setExternalSingletonInstance}.
207
208 Since Qt 6.0 you can use "" instead of a reason to use a standard message
209 instead.
210
211 \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_ANONYMOUS
212*/
213
214/*!
215 \macro QML_SINGLETON
216 \relates <qqmlintegration.h>
217
218 Declares the enclosing type to be a singleton in QML. This only takes effect
219 if the type is a \l Q_OBJECT and is available in QML (by having a
220 \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro). Unless the type is explicitly
221 marked as uncreatable with the \l QML_UNCREATABLE() macro, each QQmlEngine
222 will try to create a singleton instance using either the type's default
223 constructor or a static factory function of the signature
224 \c{T *create(QQmlEngine *, QJSEngine *)} when the type is first accessed.
225 If both do exist and are accessible, the default constructor is preferred.
226
227 If there is no default constructor and no factory function and no instance
228 was set on the engine explicitly using
229 \l{QQmlEngine::setExternalSingletonInstance} the singleton is inaccessible.
230 If the QML engine instantiated the singleton, the engine generally assumes
231 ownership of the singleton and will delete it when the engine itself is
232 destroyed. In contrast, the engine does not assume ownership of external
233 singletons unless explicitly instructed to do so. You can control this
234 behavior by calling QJSEngine::setObjectOwnership() on the singleton to
235 explicitly specify the intended behavior.
236
237 In order to declare a default-constructible class as singleton, all you have
238 to do is add \l QML_SINGLETON:
239
240 \code
241 class MySingleton : public QObject
242 {
243 Q_OBJECT
244 QML_ELEMENT
245 QML_SINGLETON
246 // Q_PROPERTY( ... )
247 public:
248 // members, Q_INVOKABLE functions, etc.
249 };
250 \endcode
251
252 If the singleton class is not default-constructible, but you can modify it,
253 you can add a factory function to it, in order to make it accessible:
254
255 \code
256 class MySingleton : public QObject
257 {
258 Q_OBJECT
259 QML_ELEMENT
260 QML_SINGLETON
261 // Q_PROPERTY( ... )
262
263 public:
264 static MySingleton *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine)
265 {
266 MySingleton *result = nullptr;
267 // Create the object using some custom constructor or factory.
268 // The QML engine will assume ownership and delete it, eventually.
269 return result;
270 }
271
272 // members, Q_INVOKABLE functions, etc
273 };
274 \endcode
275
276 If you want to provide an instance to the engine instead of letting the
277 engine instantiate it when needed, you can use \l QML_UNCREATABLE() macro.
278 In that case, the type does not have to be default constructable or have
279 a factory function:
280
281 \code
282 class MySingleton : public QObject
283 {
284 Q_OBJECT
285 QML_ELEMENT
286 QML_SINGLETON
287 QML_UNCREATABLE("Provided by C++")
288 // Q_PROPERTY( ... )
289 public:
290 MySingleton(BackendObject* backend, QObject* parent);
291
292 // members, Q_INVOKABLE functions, etc
293 };
294 \endcode
295
296 This requires an instance of \c{MySingleton} is set on the engine using
297 \c {QQmlEngine::setExternalSingletonInstance()} before the singleton is first
298 accessed from QML. This is a replacement for the
299 \l qmlRegisterSingletonInstance function.
300
301 If you cannot modify the class and it does not have a default constructor or a
302 suitable factory function, you can provide a \l QML_FOREIGN wrapper to define
303 the factory function:
304
305 \code
306 struct SingletonForeign
307 {
308 Q_GADGET
309 QML_FOREIGN(MySingleton)
310 QML_SINGLETON
311 QML_NAMED_ELEMENT(MySingleton)
312 public:
313
314 static MySingleton *create(QQmlEngine *, QJSEngine *engine)
315 {
316 MySingleton *result = nullptr;
317 // Create the instance using some custom constructor or factory.
318 // The QML engine will assume ownership and delete it, eventually.
319 return result;
320 }
321 };
322 \endcode
323
324 The QML_FOREIGN approach to declare a singleton you cannot alter also works
325 in combination with QML_UNCREATABLE(). No factory function is needed then, but
326 as before, the instance has to be set on the engine before first use:
327
328 \code
329 struct SingletonForeign
330 {
331 Q_GADGET
332 QML_FOREIGN(MySingleton)
333 QML_SINGLETON
334 QML_NAMED_ELEMENT(MySingleton)
335 QML_UNCREATABLE("Provided from C++")
336 };
337 \endcode
338
339 \sa QML_ELEMENT, QML_NAMED_ELEMENT(),
340 qmlRegisterSingletonInstance(), QQmlEngine::singletonInstance(),
341 QQmlEngine::setExternalSingletonInstance(), {Singletons in QML}
342*/
343
344/*!
345 \macro QML_ADDED_IN_VERSION(MAJOR, MINOR)
346 \relates <qqmlintegration.h>
347
348 Declares that the enclosing type or namespace was added in the specified
349 \a{MAJOR}.\a{MINOR} version. The version is assumed to be in line with any
350 revisions given by \l Q_REVISION() macros on methods, slots, or signals,
351 and any REVISION() attributes on properties declared with \l Q_PROPERTY().
352
353 \l QML_ADDED_IN_VERSION() only takes effect if the type or namespace is
354 available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(),
355 \l QML_ANONYMOUS, or \l QML_INTERFACE macro.
356
357 If the QML module the type belongs to is imported with a lower version than
358 the one determined this way, the QML type is invisible.
359
360 \sa QML_ELEMENT, QML_NAMED_ELEMENT
361*/
362
363/*!
364 \macro QML_ADDED_IN_MINOR_VERSION(VERSION)
365 \relates <qqmlintegration.h>
366 \deprecated [6.7] Use QML_ADDED_IN_VERSION and specify the full version
367
368 Declares that the enclosing type or namespace was added in the specified minor
369 \a VERSION, relative to the module major version. The minor version is assumed
370 to be in line with any revisions given by \l Q_REVISION() macros on methods,
371 slots, or signals, and any REVISION() attributes on properties declared with
372 \l Q_PROPERTY().
373
374 \l QML_ADDED_IN_MINOR_VERSION() only takes effect if the type or namespace is
375 available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(),
376 \l QML_ANONYMOUS, or \l QML_INTERFACE macro.
377
378 If the QML module the type belongs to is imported with a lower version than
379 the one determined this way, the QML type is invisible.
380
381 \sa QML_ADDED_IN_VERSION, QML_ELEMENT, QML_NAMED_ELEMENT
382*/
383
384/*!
385 \macro QML_REMOVED_IN_VERSION(MAJOR, MINOR)
386 \relates <qqmlintegration.h>
387
388 Declares that the enclosing type or namespace was removed in the specified
389 \a{MAJOR}.\a{MINOR} version. This is primarily useful when replacing the
390 implementation of a QML type. If a corresponding \l QML_ADDED_IN_VERSION()
391 is present on a different type or namespace of the same QML name, then the
392 removed type is used when importing versions of the module lower than
393 \a{MAJOR}.\a{MINOR}, and the added type is used when importing
394 versions of the module greater or equal \a{MAJOR}.\a{MINOR}.
395
396 \l QML_REMOVED_IN_VERSION() only takes effect if type or namespace is
397 available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(),
398 \l QML_ANONYMOUS, or \l QML_INTERFACE macro.
399
400 \sa QML_ELEMENT, QML_NAMED_ELEMENT
401*/
402
403/*!
404 \macro QML_REMOVED_IN_MINOR_VERSION(VERSION)
405 \relates <qqmlintegration.h>
406 \deprecated [6.7] Use QML_REMOVED_IN_VERSION and specify the full version
407
408 Declares that the enclosing type or namespace was removed in the specified
409 minor \a VERSION, relative to the module major version. This is primarily
410 useful when replacing the implementation of a QML type. If a corresponding
411 \l QML_ADDED_IN_VERSION() is present on a different type or namespace of
412 the same QML name, then the removed type is used when importing versions of
413 the module lower than \a VERSION, and the added type is used when importing
414 versions of the module greater or equal \a VERSION.
415
416 \l QML_REMOVED_IN_MINOR_VERSION() only takes effect if type or namespace is
417 available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(),
418 \l QML_ANONYMOUS, or \l QML_INTERFACE macro.
419
420 \sa QML_REMOVED_IN_VERSION, QML_ELEMENT, QML_NAMED_ELEMENT
421*/
422
423/*!
424 \macro QML_EXTRA_VERSION(MAJOR, MINOR)
425 \relates <qqmlintegration.h>
426
427 Declare that the type should also be available in version \a{MAJOR}.\a{MINOR}.
428 This can be helpful if a type should be available in multiple major versions.
429
430 Types are automatically registered for:
431 \list
432 \li The major version they were introduced in, see \l{QML_ADDED_IN_VERSION}.
433 \li Any major versions any their members were introduced in.
434 \li The current major version of their module, unless they were
435 \l{QML_REMOVED_IN_VERSION} before that.
436 \endlist
437
438 Notably, they are not automatically registered in any \l{PAST_MAJOR_VERSIONS}
439 between the above. You can use QML_EXTRA_VERSION to manually register your
440 types in further major versions.
441
442 \note Keeping multiple \l{PAST_MAJOR_VERSIONS} around is computationally
443 expensive.
444
445 \sa QML_ELEMENT, QML_ADDED_IN_VERSION
446*/
447
448/*!
449 \macro QML_ATTACHED(ATTACHED_TYPE)
450 \relates <qqmlintegration.h>
451
452 Declares that the enclosing type attaches \a ATTACHED_TYPE as an
453 \l {Attached Properties and Attached Signal Handlers}
454 {attached property} to other types. This takes effect if the type
455 is exposed to QML using a \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro.
456
457 \include {qualified-class-name.qdocinc} {class name must be qualified}
458
459 \sa QML_ELEMENT, QML_NAMED_ELEMENT(), qmlAttachedPropertiesObject(),
460 {Providing Attached Properties}
461*/
462
463/*!
464 \macro QML_EXTENDED(EXTENDED_TYPE)
465 \relates <qqmlintegration.h>
466
467 Declares that the enclosing type uses \a EXTENDED_TYPE as an extension to
468 provide further properties, methods, and enumerations in QML. This takes
469 effect if the type is exposed to QML using a \l QML_ELEMENT or
470 \l QML_NAMED_ELEMENT() macro.
471
472 \warning Members of \a EXTENDED_TYPE are implicitly treated as FINAL.
473
474 \include {qualified-class-name.qdocinc} {class name must be qualified}
475
476 \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED_NAMESPACE(),
477 {Registering Extension Objects}
478*/
479
480/*!
481 \macro QML_EXTENDED_NAMESPACE(EXTENSION_NAMESPACE)
482 \relates <qqmlintegration.h>
483
484 Declares that the enclosing \b type uses \a EXTENSION_NAMESPACE as an extension to
485 provide further enumerations in QML. This takes effect if the type
486 is exposed to QML using a \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro.
487 The enumerations need to be exposed to the metaobject system for this to work.
488
489 For example, give the following C++ code
490 \code
491 namespace MyNamespace {
492 Q_NAMESPACE
493 enum MyEnum { MyEnumerator = 10 };
494 Q_ENUM_NS(MyEnum)
495 }
496
497 class QmlType : public QObject
498 {
499 Q_OBJECT
500 QML_ELEMENT
501 QML_EXTENDED_NAMESPACE(MyNamespace)
502 }
503 \endcode
504
505 we can access the enum in QML:
506 \qml
507 QmlType {
508 property int i: QmlType.MyEnumerator // i will be 10
509 }
510 \endqml
511
512 \note \a EXTENSION_NAMESPACE can also be a QObject or QGadget; in that case - and in contrast to
513 QML_EXTENDED, which also exposes methods and properties - only its enumerations
514 are exposed.
515
516 \note \a EXTENSION_NAMESPACE must have a metaobject; i.e. it must either be a namespace which
517 contains the Q_NAMESPACE macro or a QObject/QGadget.
518
519 \include {qualified-class-name.qdocinc} {class name must be qualified}
520
521 \sa QML_NAMESPACE_EXTENDED(), QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED(),
522 {Registering Extension Objects}, Q_ENUM, Q_ENUM_NS
523*/
524
525/*!
526 \macro QML_NAMESPACE_EXTENDED(EXTENSION_NAMESPACE)
527 \relates QQmlEngine
528
529 Behaves the same way as \l QML_EXTENDED_NAMESPACE with the distinction that what is being
530 extended is a namespace and not a type.
531
532 Declares that the enclosing \b namespace uses \a EXTENSION_NAMESPACE as an extension to
533 provide further enumerations in QML. This takes effect if the extended namespace is exposed to
534 QML using a \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro. The enumerations need to be exposed
535 to the metaobject system for this to work.
536
537 For example, in the following C++ code,
538 \code
539 namespace NS2 {
540 Q_NAMESPACE
541
542 enum class E2 { D = 3, E, F };
543 Q_ENUM_NS(E2)
544 }
545
546 namespace NS1 {
547 Q_NAMESPACE
548 QML_ELEMENT
549
550 enum class E1 { A, B, C };
551 Q_ENUM_NS(E1)
552
553 // Extends NS1 with NS2
554 QML_NAMESPACE_EXTENDED(NS2)
555 }
556 \endcode
557
558 the namespace \c NS1 is extended with \c NS2 and the \c E2 enum becomes available within \c NS1
559 from QML.
560 \qml
561 Item {
562 Component.onCompleted: console.log(NS1.E1.A, NS1.E2.D)
563 }
564 \endqml
565
566 \note \a EXTENSION_NAMESPACE can also be a QObject or QGadget; in that case - and in contrast to
567 QML_EXTENDED, which also exposes methods and properties - only its enumerations
568 are exposed.
569
570 \note \a EXTENSION_NAMESPACE must have a metaobject; i.e. it must either be a namespace which
571 contains the Q_NAMESPACE macro or a QObject/QGadget.
572
573 \include {qualified-class-name.qdocinc} {class name must be qualified}
574
575 \sa QML_EXTENDED_NAMESPACE(), QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED(),
576 {Registering Extension Objects}, Q_ENUM, Q_ENUM_NS
577*/
578
579/*!
580 \macro QML_FOREIGN(FOREIGN_TYPE)
581 \relates <qqmlintegration.h>
582
583 Declares that any \l QML_ELEMENT, \l QML_NAMED_ELEMENT(), \l QML_ANONYMOUS,
584 \l QML_INTERFACE, \l QML_UNCREATABLE(), \l QML_SINGLETON,
585 \l QML_ADDED_IN_VERSION(), \l QML_REMOVED_IN_VERSION(),
586 \l QML_ADDED_IN_MINOR_VERSION(), \l QML_REMOVED_IN_MINOR_VERSION(),
587 \l QML_EXTENDED(), \l QML_EXTENDED_NAMESPACE(), or \l QML_NAMESPACE_EXTENDED()
588 macros in the enclosing C++ type do not apply to the enclosing type but
589 instead to \a FOREIGN_TYPE. The enclosing type still needs to be registered
590 with the \l {The Meta-Object System}{meta object system} using a \l Q_GADGET
591 or \l Q_OBJECT macro.
592
593 This is useful for registering types that cannot be amended to add the macros,
594 for example because they belong to 3rdparty libraries.
595 To register a namespace, see \l QML_FOREIGN_NAMESPACE().
596
597 \note You may want to use \l QML_NAMED_ELEMENT() instead of \l QML_ELEMENT.
598 With QML_ELEMENT, the element is named after the struct it is contained in,
599 not the foreign type. The \l {Foreign objects integration} chapter in
600 \l {Writing advanced QML Extensions with C++} demonstrates this.
601
602 \note QML_ATTACHED() can currently not be redirected like this. It has to be
603 specificed in the same type that implements qmlAttachedProperties().
604
605 \include {qualified-class-name.qdocinc} {class name must be qualified}
606
607 \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_FOREIGN_NAMESPACE()
608*/
609
610/*!
611 \macro QML_FOREIGN_NAMESPACE(FOREIGN_NAMESPACE)
612 \relates <qqmlintegration.h>
613
614 Declares that any \l QML_ELEMENT, \l QML_NAMED_ELEMENT(), \l QML_ANONYMOUS,
615 \l QML_INTERFACE, \l QML_UNCREATABLE(), \l QML_SINGLETON,
616 \l QML_ADDED_IN_VERSION(), \l QML_REMOVED_IN_VERSION(),
617 \l QML_ADDED_IN_MINOR_VERSION(), or \l QML_REMOVED_IN_MINOR_VERSION()
618 macros in the enclosing C++ namespace do not apply to the enclosing type but
619 instead to \a FOREIGN_NAMESPACE. The enclosing namespace still needs to be
620 registered with the \l {The Meta-Object System}{meta object system} using a
621 \l Q_NAMESPACE macro.
622
623 This is useful for registering namespaces that cannot be amended to add the macros,
624 for example because they belong to 3rdparty libraries.
625
626 \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_FOREIGN()
627*/
628
629/*!
630 \macro QML_UNAVAILABLE
631 \relates <qqmlintegration.h>
632
633 This macro declares the enclosing type to be unavailable in QML. It registers
634 an internal dummy type called \c QQmlTypeNotAvailable as \l QML_FOREIGN()
635 type, using any further QML macros you specify.
636
637 Normally, the types exported by a module should be fixed. However, if a C++
638 type is not available, you should at least "reserve" the QML type name, and
639 give the user of the unavailable type a meaningful error message.
640
641 Example:
642
643 \code
644 #ifdef NO_GAMES_ALLOWED
645 struct MinehuntGame
646 {
647 Q_GADGET
648 QML_NAMED_ELEMENT(Game)
649 QML_UNAVAILABLE
650 QML_UNCREATABLE("Get back to work, slacker!");
651 };
652 #else
653 class MinehuntGame : public QObject
654 {
655 Q_OBJECT
656 QML_NAMED_ELEMENT(Game)
657 // ...
658 };
659 #endif
660 \endcode
661
662 This will cause any QML which attempts to use the "Game" type to produce an
663 error message:
664
665 \badcode
666 fun.qml: Get back to work, slacker!
667 Game {
668 ^
669 \endcode
670
671 Using this technique, you only need a \l Q_GADGET struct to customize the error
672 message, not a full-blown \l QObject. Without \l QML_UNCREATABLE(),
673 \l QML_UNAVAILABLE still results in a more specific error message than the usual
674 "is not a type" for completely unknown types.
675
676 \include {qualified-class-name.qdocinc} {class name must be qualified}
677
678 \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), QML_FOREIGN()
679*/
680
681/*!
682 \macro QML_SEQUENTIAL_CONTAINER(VALUE_TYPE)
683 \relates <qqmlintegration.h>
684
685 This macro declares the enclosing or referenced type as a sequential container
686 managing a sequence of \a VALUE_TYPE elements. \a VALUE_TYPE can be an actual
687 \l{QML Value Types}{value type} or a pointer to an
688 \l{QML Object Types}{object type}. You will rarely be able to add this macro
689 to the actual container declaration since containers are usually templates.
690 You should use \l{QML_FOREIGN} to attach the type registration to a template
691 instantiation. Using this technique you can, for example, declare sequential
692 containers like this:
693
694 \code
695 class IntDequeRegistration
696 {
697 Q_GADGET
698 QML_FOREIGN(std::deque<int>)
699 QML_ANONYMOUS
700 QML_SEQUENTIAL_CONTAINER(int)
701 };
702 \endcode
703
704 After this, you can use the container like a JavaScript array in QML.
705
706 \code
707 class Maze
708 {
709 Q_OBJECT
710 Q_ELEMENT
711 // 0: North, 1: East, 2: South, 3: West
712 Q_PROPERTY(std::deque<int> solution READ solution CONSTANT FINAL)
713 [...]
714 }
715 \endcode
716
717 \code
718 Item {
719 Maze {
720 id: maze
721 }
722
723 function showSolution() {
724 maze.solution.forEach([...])
725 }
726 }
727 \endcode
728
729 \note For \l{QML Value Types} \l{QList} is automatically registered as
730 sequential container. For \l{QML Object Types} \l{QQmlListProperty} is.
731 You don't have to add these registrations.
732
733 \note You cannot currently give the container a custom name. Any argument
734 passed to \l{QML_NAMED_ELEMENT} is ignored. The automatically registered
735 sequential containers are available under the familiar \e{list<...>} names,
736 for example \e{list<QtObject>} or \e{list<font>}.
737
738 \include {qualified-class-name.qdocinc} {class name must be qualified}
739
740 \sa QML_ANONYMOUS, QML_FOREIGN()
741*/
742
743/*!
744 \macro QML_VALUE_TYPE(name)
745 \relates <qqmlintegration.h>
746
747 Declares the enclosing type or namespace to be available in QML, using \a name
748 as the name. The type has to be a value type and the name has to be lower case.
749
750 \code
751 class MyValueType
752 {
753 Q_GADGET
754 QML_VALUE_TYPE(myValueType)
755
756 // ...
757 };
758 \endcode
759
760 \sa {Choosing the Correct Integration Method Between C++ and QML}, QML_NAMED_ELEMENT
761*/
762
763/*!
764 \macro QML_CONSTRUCTIBLE_VALUE
765 \since 6.5
766 \relates <qqmlintegration.h>
767
768 Marks the surrounding value type as constructible. That is, any \l Q_INVOKABLE
769 constructors of the type that take exactly one argument can be used when
770 assigning a JavaScript value to a property of this type.
771
772 You can declare a constructible value type as follows:
773
774 \code
775 class MyValueType
776 {
777 Q_GADGET
778 QML_VALUE_TYPE(myValueType)
779 QML_CONSTRUCTIBLE_VALUE
780 public:
781 Q_INVOKABLE MyValueType(double d);
782
783 // ...
784 };
785 \endcode
786
787 With the above type, the following QML code will produce a \c MyValueType
788 value using the given constructor and assign it to the property.
789
790 \qml
791 QtObject {
792 property myValueType v: 5.4
793 }
794 \endqml
795
796 You can also construct lists of values this way:
797
798 \qml
799 QtObject {
800 property list<myValueType> v: [5.4, 4.5, 3.3]
801 }
802 \endqml
803
804 Since Qt 6.8, if you import the QML module the value type belongs to into a
805 namespace, you can use JavaScript's \c new operator to instantiate it.
806
807 \qml
808 import MyModule as MM
809
810 QtObject {
811 function process(d: real) {
812 let v = new MM.myValueType(d);
813 // v is a myValueType now
814 }
815 }
816 \endqml
817
818 \sa QML_VALUE_TYPE
819*/
820
821/*!
822 \macro QML_STRUCTURED_VALUE
823 \since 6.5
824 \relates <qqmlintegration.h>
825
826 Marks the surrounding value type as structured. Structured value types can
827 and will preferably be constructed property-by-property from a JavaScript
828 object. A structured value type, however is always \l QML_CONSTRUCTIBLE_VALUE,
829 too. This means, you can still provide \l Q_INVOKABLE constructors in order to
830 handle construction from primitive types.
831
832 You can declare a structured value type as follows:
833
834 \code
835 class MyValueType
836 {
837 Q_GADGET
838 QML_VALUE_TYPE(myValueType)
839 QML_STRUCTURED_VALUE
840 Q_PROPERTY(double d READ d WRITE setD)
841 Q_PROPERTY(string e READ e WRITE setE)
842
843 // ...
844 };
845 \endcode
846
847 Then you can populate a property of this type as follows:
848
849 \qml
850 QtObject {
851 property myValueType v: ({d: 4.4, e: "a string"})
852 }
853 \endqml
854
855 The extra parentheses are necessary to disambiguate the JavaScript object
856 from what might be interpreted as a JavaScript code block.
857
858 You can also construct lists of values this way:
859
860 \qml
861 QtObject {
862 property list<myValueType> v: [
863 {d: 4.4, e: "a string"},
864 {d: 7.1, e: "another string"}
865 ]
866 }
867 \endqml
868
869 \sa QML_VALUE_TYPE QML_CONSTRUCTIBLE_VALUE
870*/