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 \title Registering C++ types to QML
9 \keyword qqmlintegration.h
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 Since Qt 6.0 you can use "" instead of a reason to use a standard message
205 instead.
206
207 \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_ANONYMOUS
208*/
209
210/*!
211 \macro QML_SINGLETON
212 \relates <qqmlintegration.h>
213
214 Declares the enclosing type to be a singleton in QML. This only takes effect
215 if the type is a \l Q_OBJECT and is available in QML (by having a
216 \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro). By default, each QQmlEngine
217 will try to create a singleton instance using either the type's default
218 constructor or a static factory function of the signature
219 \c{T *create(QQmlEngine *, QJSEngine *)} when the type is first accessed.
220 If both do exist and are accessible, the default constructor is preferred.
221 If there is no default constructor and no factory function the singleton is
222 inaccessible. The QML engine generally assumes ownership of the singleton and
223 will delete it when the engine itself is destroyed. You can prevent this by
224 calling QJSEngine::setObjectOwnership() on the singleton.
225
226 In order to declare a default-constructible class as singleton, all you have
227 to do is add \l QML_SINGLETON:
228
229 \code
230 class MySingleton : public QObject
231 {
232 Q_OBJECT
233 QML_ELEMENT
234 QML_SINGLETON
235 // Q_PROPERTY( ... )
236 public:
237 // members, Q_INVOKABLE functions, etc.
238 };
239 \endcode
240
241 If the singleton class is not default-constructible, but you can modify it,
242 you can add a factory function to it, in order to make it accessible:
243
244 \code
245 class MySingleton : public QObject
246 {
247 Q_OBJECT
248 QML_ELEMENT
249 QML_SINGLETON
250 // Q_PROPERTY( ... )
251
252 public:
253 static MySingleton *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine)
254 {
255 MySingleton *result = nullptr;
256 // Create the object using some custom constructor or factory.
257 // The QML engine will assume ownership and delete it, eventually.
258 return result;
259 }
260
261 // members, Q_INVOKABLE functions, etc
262 };
263 \endcode
264
265 If you cannot modify the class and it does not have a default constructor or a
266 suitable factory function, you can provide a \l QML_FOREIGN wrapper to define
267 the factory function:
268
269 \code
270 struct SingletonForeign
271 {
272 Q_GADGET
273 QML_FOREIGN(MySingleton)
274 QML_SINGLETON
275 QML_NAMED_ELEMENT(MySingleton)
276 public:
277
278 static MySingleton *create(QQmlEngine *, QJSEngine *engine)
279 {
280 MySingleton *result = nullptr;
281 // Create the instance using some custom constructor or factory.
282 // The QML engine will assume ownership and delete it, eventually.
283 return result;
284 }
285 };
286 \endcode
287
288 Finally, if you want to provide one specific singleton object, the creation of
289 which you cannot control, you can return that from a factory function. This is
290 a replacement for the \l qmlRegisterSingletonInstance function.
291 If you were calling
292
293 \code
294 qmlRegisterSingletonInstance("MyModule", 1, 0, "MySingleton", myObject);
295 \endcode
296
297 with myObject being of type \c{MySingleton *}, you can do the following
298 instead:
299
300 \code
301 struct SingletonForeign
302 {
303 Q_GADGET
304 QML_FOREIGN(MySingleton)
305 QML_SINGLETON
306 QML_NAMED_ELEMENT(MySingleton)
307 public:
308
309 // Initialize this using myObject where you would previously
310 // call qmlRegisterSingletonInstance().
311 inline static MySingleton *s_singletonInstance = nullptr;
312
313 static MySingleton *create(QQmlEngine *, QJSEngine *engine)
314 {
315 // The instance has to exist before it is used. We cannot replace it.
316 Q_ASSERT(s_singletonInstance);
317
318 // The engine has to have the same thread affinity as the singleton.
319 Q_ASSERT(engine->thread() == s_singletonInstance->thread());
320
321 // There can only be one engine accessing the singleton.
322 if (s_engine)
323 Q_ASSERT(engine == s_engine);
324 else
325 s_engine = engine;
326
327 // Explicitly specify C++ ownership so that the engine doesn't delete
328 // the instance.
329 QJSEngine::setObjectOwnership(s_singletonInstance,
330 QJSEngine::CppOwnership);
331 return s_singletonInstance;
332 }
333
334 private:
335 inline static QJSEngine *s_engine = nullptr;
336 };
337 \endcode
338
339 This way, the pre-existing class \c MySingleton is declared to be a QML
340 singleton, called \c MySingleton. You can specify an instance for it any time
341 before it is used by setting the \c s_singletonInstance member. None of this
342 requires modification of \c MySingleton itself.
343
344 \note This pattern doesn't work if either the singleton is accessed by
345 multiple QML engines, or if the QML engine accessing it has a different thread
346 affinity than the singleton object itself. As shown above, you can check the
347 parameters to the \c create() method for identity and thread affinity of the
348 engine in order to assert on that.
349
350 \sa QML_ELEMENT, QML_NAMED_ELEMENT(),
351 qmlRegisterSingletonInstance(), QQmlEngine::singletonInstance(), {Singletons in QML}
352*/
353
354/*!
355 \macro QML_ADDED_IN_VERSION(MAJOR, MINOR)
356 \relates <qqmlintegration.h>
357
358 Declares that the enclosing type or namespace was added in the specified
359 \a{MAJOR}.\a{MINOR} version. The version is assumed to be in line with any
360 revisions given by \l Q_REVISION() macros on methods, slots, or signals,
361 and any REVISION() attributes on properties declared with \l Q_PROPERTY().
362
363 \l QML_ADDED_IN_VERSION() only takes effect if the type or namespace is
364 available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(),
365 \l QML_ANONYMOUS, or \l QML_INTERFACE macro.
366
367 If the QML module the type belongs to is imported with a lower version than
368 the one determined this way, the QML type is invisible.
369
370 \sa QML_ELEMENT, QML_NAMED_ELEMENT
371*/
372
373/*!
374 \macro QML_ADDED_IN_MINOR_VERSION(VERSION)
375 \relates <qqmlintegration.h>
376 \deprecated [6.7] Use QML_ADDED_IN_VERSION and specify the full version
377
378 Declares that the enclosing type or namespace was added in the specified minor
379 \a VERSION, relative to the module major version. The minor version is assumed
380 to be in line with any revisions given by \l Q_REVISION() macros on methods,
381 slots, or signals, and any REVISION() attributes on properties declared with
382 \l Q_PROPERTY().
383
384 \l QML_ADDED_IN_MINOR_VERSION() only takes effect if the type or namespace is
385 available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(),
386 \l QML_ANONYMOUS, or \l QML_INTERFACE macro.
387
388 If the QML module the type belongs to is imported with a lower version than
389 the one determined this way, the QML type is invisible.
390
391 \sa QML_ADDED_IN_VERSION, QML_ELEMENT, QML_NAMED_ELEMENT
392*/
393
394/*!
395 \macro QML_REMOVED_IN_VERSION(MAJOR, MINOR)
396 \relates <qqmlintegration.h>
397
398 Declares that the enclosing type or namespace was removed in the specified
399 \a{MAJOR}.\a{MINOR} version. This is primarily useful when replacing the
400 implementation of a QML type. If a corresponding \l QML_ADDED_IN_VERSION()
401 is present on a different type or namespace of the same QML name, then the
402 removed type is used when importing versions of the module lower than
403 \a{MAJOR}.\a{MINOR}, and the added type is used when importing
404 versions of the module greater or equal \a{MAJOR}.\a{MINOR}.
405
406 \l QML_REMOVED_IN_VERSION() only takes effect if type or namespace is
407 available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(),
408 \l QML_ANONYMOUS, or \l QML_INTERFACE macro.
409
410 \sa QML_ELEMENT, QML_NAMED_ELEMENT
411*/
412
413/*!
414 \macro QML_REMOVED_IN_MINOR_VERSION(VERSION)
415 \relates <qqmlintegration.h>
416 \deprecated [6.7] Use QML_REMOVED_IN_VERSION and specify the full version
417
418 Declares that the enclosing type or namespace was removed in the specified
419 minor \a VERSION, relative to the module major version. This is primarily
420 useful when replacing the implementation of a QML type. If a corresponding
421 \l QML_ADDED_IN_VERSION() is present on a different type or namespace of
422 the same QML name, then the removed type is used when importing versions of
423 the module lower than \a VERSION, and the added type is used when importing
424 versions of the module greater or equal \a VERSION.
425
426 \l QML_REMOVED_IN_MINOR_VERSION() only takes effect if type or namespace is
427 available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(),
428 \l QML_ANONYMOUS, or \l QML_INTERFACE macro.
429
430 \sa QML_REMOVED_IN_VERSION, QML_ELEMENT, QML_NAMED_ELEMENT
431*/
432
433/*!
434 \macro QML_EXTRA_VERSION(MAJOR, MINOR)
435 \relates <qqmlintegration.h>
436
437 Declare that the type should also be available in version \a{MAJOR}.\a{MINOR}.
438 This can be helpful if a type should be available in multiple major versions.
439
440 Types are automatically registered for:
441 \list
442 \li The major version they were introduced in, see \l{QML_ADDED_IN_VERSION}.
443 \li Any major versions any their members were introduced in.
444 \li The current major version of their module, unless they were
445 \l{QML_REMOVED_IN_VERSION} before that.
446 \endlist
447
448 Notably, they are not automatically registered in any \l{PAST_MAJOR_VERSIONS}
449 between the above. You can use QML_EXTRA_VERSION to manually register your
450 types in further major versions.
451
452 \note Keeping multiple \l{PAST_MAJOR_VERSIONS} around is computationally
453 expensive.
454
455 \sa QML_ELEMENT, QML_ADDED_IN_VERSION
456*/
457
458/*!
459 \macro QML_ATTACHED(ATTACHED_TYPE)
460 \relates <qqmlintegration.h>
461
462 Declares that the enclosing type attaches \a ATTACHED_TYPE as an
463 \l {Attached Properties and Attached Signal Handlers}
464 {attached property} to other types. This takes effect if the type
465 is exposed to QML using a \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro.
466
467 \include {qualified-class-name.qdocinc} {class name must be qualified}
468
469 \sa QML_ELEMENT, QML_NAMED_ELEMENT(), qmlAttachedPropertiesObject(),
470 {Providing Attached Properties}
471*/
472
473/*!
474 \macro QML_EXTENDED(EXTENDED_TYPE)
475 \relates <qqmlintegration.h>
476
477 Declares that the enclosing type uses \a EXTENDED_TYPE as an extension to
478 provide further properties, methods, and enumerations in QML. This takes
479 effect if the type is exposed to QML using a \l QML_ELEMENT or
480 \l QML_NAMED_ELEMENT() macro.
481
482 \warning Members of \a EXTENDED_TYPE are implicitly treated as FINAL.
483
484 \include {qualified-class-name.qdocinc} {class name must be qualified}
485
486 \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED_NAMESPACE(),
487 {Registering Extension Objects}
488*/
489
490/*!
491 \macro QML_EXTENDED_NAMESPACE(EXTENSION_NAMESPACE)
492 \relates <qqmlintegration.h>
493
494 Declares that the enclosing \b type uses \a EXTENSION_NAMESPACE as an extension to
495 provide further enumerations in QML. This takes effect if the type
496 is exposed to QML using a \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro.
497 The enumerations need to be exposed to the metaobject system for this to work.
498
499 For example, give the following C++ code
500 \code
501 namespace MyNamespace {
502 Q_NAMESPACE
503 enum MyEnum { MyEnumerator = 10 };
504 Q_ENUM_NS(MyEnum)
505 }
506
507 class QmlType : public QObject
508 {
509 Q_OBJECT
510 QML_ELEMENT
511 QML_EXTENDED_NAMESPACE(MyNamespace)
512 }
513 \endcode
514
515 we can access the enum in QML:
516 \qml
517 QmlType {
518 property int i: QmlType.MyEnumerator // i will be 10
519 }
520 \endqml
521
522 \note \a EXTENSION_NAMESPACE can also be a QObject or QGadget; in that case - and in contrast to
523 QML_EXTENDED, which also exposes methods and properties - only its enumerations
524 are exposed.
525
526 \note \a EXTENSION_NAMESPACE must have a metaobject; i.e. it must either be a namespace which
527 contains the Q_NAMESPACE macro or a QObject/QGadget.
528
529 \include {qualified-class-name.qdocinc} {class name must be qualified}
530
531 \sa QML_NAMESPACE_EXTENDED(), QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED(),
532 {Registering Extension Objects}, Q_ENUM, Q_ENUM_NS
533*/
534
535/*!
536 \macro QML_NAMESPACE_EXTENDED(EXTENSION_NAMESPACE)
537 \relates QQmlEngine
538
539 Behaves the same way as \l QML_EXTENDED_NAMESPACE with the distinction that what is being
540 extended is a namespace and not a type.
541
542 Declares that the enclosing \b namespace uses \a EXTENSION_NAMESPACE as an extension to
543 provide further enumerations in QML. This takes effect if the extended namespace is exposed to
544 QML using a \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro. The enumerations need to be exposed
545 to the metaobject system for this to work.
546
547 For example, in the following C++ code,
548 \code
549 namespace NS2 {
550 Q_NAMESPACE
551
552 enum class E2 { D = 3, E, F };
553 Q_ENUM_NS(E2)
554 }
555
556 namespace NS1 {
557 Q_NAMESPACE
558 QML_ELEMENT
559
560 enum class E1 { A, B, C };
561 Q_ENUM_NS(E1)
562
563 // Extends NS1 with NS2
564 QML_NAMESPACE_EXTENDED(NS2)
565 }
566 \endcode
567
568 the namespace \c NS1 is extended with \c NS2 and the \c E2 enum becomes available within \c NS1
569 from QML.
570 \qml
571 Item {
572 Component.onCompleted: console.log(NS1.E1.A, NS1.E2.D)
573 }
574 \endqml
575
576 \note \a EXTENSION_NAMESPACE can also be a QObject or QGadget; in that case - and in contrast to
577 QML_EXTENDED, which also exposes methods and properties - only its enumerations
578 are exposed.
579
580 \note \a EXTENSION_NAMESPACE must have a metaobject; i.e. it must either be a namespace which
581 contains the Q_NAMESPACE macro or a QObject/QGadget.
582
583 \include {qualified-class-name.qdocinc} {class name must be qualified}
584
585 \sa QML_EXTENDED_NAMESPACE(), QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED(),
586 {Registering Extension Objects}, Q_ENUM, Q_ENUM_NS
587*/
588
589/*!
590 \macro QML_FOREIGN(FOREIGN_TYPE)
591 \relates <qqmlintegration.h>
592
593 Declares that any \l QML_ELEMENT, \l QML_NAMED_ELEMENT(), \l QML_ANONYMOUS,
594 \l QML_INTERFACE, \l QML_UNCREATABLE(), \l QML_SINGLETON,
595 \l QML_ADDED_IN_VERSION(), \l QML_REMOVED_IN_VERSION(),
596 \l QML_ADDED_IN_MINOR_VERSION(), \l QML_REMOVED_IN_MINOR_VERSION(),
597 \l QML_EXTENDED(), \l QML_EXTENDED_NAMESPACE(), or \l QML_NAMESPACE_EXTENDED()
598 macros in the enclosing C++ type do not apply to the enclosing type but
599 instead to \a FOREIGN_TYPE. The enclosing type still needs to be registered
600 with the \l {The Meta-Object System}{meta object system} using a \l Q_GADGET
601 or \l Q_OBJECT macro.
602
603 This is useful for registering types that cannot be amended to add the macros,
604 for example because they belong to 3rdparty libraries.
605 To register a namespace, see \l QML_FOREIGN_NAMESPACE().
606
607 \note You may want to use \l QML_NAMED_ELEMENT() instead of \l QML_ELEMENT.
608 With QML_ELEMENT, the element is named after the struct it is contained in,
609 not the foreign type. The \l {Foreign objects integration} chapter in
610 \l {Writing advanced QML Extensions with C++} demonstrates this.
611
612 \note QML_ATTACHED() can currently not be redirected like this. It has to be
613 specificed in the same type that implements qmlAttachedProperties().
614
615 \include {qualified-class-name.qdocinc} {class name must be qualified}
616
617 \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_FOREIGN_NAMESPACE()
618*/
619
620/*!
621 \macro QML_FOREIGN_NAMESPACE(FOREIGN_NAMESPACE)
622 \relates <qqmlintegration.h>
623
624 Declares that any \l QML_ELEMENT, \l QML_NAMED_ELEMENT(), \l QML_ANONYMOUS,
625 \l QML_INTERFACE, \l QML_UNCREATABLE(), \l QML_SINGLETON,
626 \l QML_ADDED_IN_VERSION(), \l QML_REMOVED_IN_VERSION(),
627 \l QML_ADDED_IN_MINOR_VERSION(), or \l QML_REMOVED_IN_MINOR_VERSION()
628 macros in the enclosing C++ namespace do not apply to the enclosing type but
629 instead to \a FOREIGN_NAMESPACE. The enclosing namespace still needs to be
630 registered with the \l {The Meta-Object System}{meta object system} using a
631 \l Q_NAMESPACE macro.
632
633 This is useful for registering namespaces that cannot be amended to add the macros,
634 for example because they belong to 3rdparty libraries.
635
636 \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_FOREIGN()
637*/
638
639/*!
640 \macro QML_UNAVAILABLE
641 \relates <qqmlintegration.h>
642
643 This macro declares the enclosing type to be unavailable in QML. It registers
644 an internal dummy type called \c QQmlTypeNotAvailable as \l QML_FOREIGN()
645 type, using any further QML macros you specify.
646
647 Normally, the types exported by a module should be fixed. However, if a C++
648 type is not available, you should at least "reserve" the QML type name, and
649 give the user of the unavailable type a meaningful error message.
650
651 Example:
652
653 \code
654 #ifdef NO_GAMES_ALLOWED
655 struct MinehuntGame
656 {
657 Q_GADGET
658 QML_NAMED_ELEMENT(Game)
659 QML_UNAVAILABLE
660 QML_UNCREATABLE("Get back to work, slacker!");
661 };
662 #else
663 class MinehuntGame : public QObject
664 {
665 Q_OBJECT
666 QML_NAMED_ELEMENT(Game)
667 // ...
668 };
669 #endif
670 \endcode
671
672 This will cause any QML which attempts to use the "Game" type to produce an
673 error message:
674
675 \badcode
676 fun.qml: Get back to work, slacker!
677 Game {
678 ^
679 \endcode
680
681 Using this technique, you only need a \l Q_GADGET struct to customize the error
682 message, not a full-blown \l QObject. Without \l QML_UNCREATABLE(),
683 \l QML_UNAVAILABLE still results in a more specific error message than the usual
684 "is not a type" for completely unknown types.
685
686 \include {qualified-class-name.qdocinc} {class name must be qualified}
687
688 \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), QML_FOREIGN()
689*/
690
691/*!
692 \macro QML_SEQUENTIAL_CONTAINER(VALUE_TYPE)
693 \relates <qqmlintegration.h>
694
695 This macro declares the enclosing or referenced type as a sequential container
696 managing a sequence of \a VALUE_TYPE elements. \a VALUE_TYPE can be an actual
697 \l{QML Value Types}{value type} or a pointer to an
698 \l{QML Object Types}{object type}. You will rarely be able to add this macro
699 to the actual container declaration since containers are usually templates.
700 You should use \l{QML_FOREIGN} to attach the type registration to a template
701 instantiation. Using this technique you can, for example, declare sequential
702 containers like this:
703
704 \code
705 class IntDequeRegistration
706 {
707 Q_GADGET
708 QML_FOREIGN(std::deque<int>)
709 QML_ANONYMOUS
710 QML_SEQUENTIAL_CONTAINER(int)
711 };
712 \endcode
713
714 After this, you can use the container like a JavaScript array in QML.
715
716 \code
717 class Maze
718 {
719 Q_OBJECT
720 Q_ELEMENT
721 // 0: North, 1: East, 2: South, 3: West
722 Q_PROPERTY(std::deque<int> solution READ solution CONSTANT FINAL)
723 [...]
724 }
725 \endcode
726
727 \code
728 Item {
729 Maze {
730 id: maze
731 }
732
733 function showSolution() {
734 maze.solution.forEach([...])
735 }
736 }
737 \endcode
738
739 \note For \l{QML Value Types} \l{QList} is automatically registered as
740 sequential container. For \l{QML Object Types} \l{QQmlListProperty} is.
741 You don't have to add these registrations.
742
743 \note You cannot currently give the container a custom name. Any argument
744 passed to \l{QML_NAMED_ELEMENT} is ignored. The automatically registered
745 sequential containers are available under the familiar \e{list<...>} names,
746 for example \e{list<QtObject>} or \e{list<font>}.
747
748 \include {qualified-class-name.qdocinc} {class name must be qualified}
749
750 \sa QML_ANONYMOUS, QML_FOREIGN()
751*/
752
753/*!
754 \macro QML_VALUE_TYPE(name)
755 \relates <qqmlintegration.h>
756
757 Declares the enclosing type or namespace to be available in QML, using \a name
758 as the name. The type has to be a value type and the name has to be lower case.
759
760 \code
761 class MyValueType
762 {
763 Q_GADGET
764 QML_VALUE_TYPE(myValueType)
765
766 // ...
767 };
768 \endcode
769
770 \sa {Choosing the Correct Integration Method Between C++ and QML}, QML_NAMED_ELEMENT
771*/
772
773/*!
774 \macro QML_CONSTRUCTIBLE_VALUE
775 \since 6.5
776 \relates <qqmlintegration.h>
777
778 Marks the surrounding value type as constructible. That is, any \l Q_INVOKABLE
779 constructors of the type that take exactly one argument can be used when
780 assigning a JavaScript value to a property of this type.
781
782 You can declare a constructible value type as follows:
783
784 \code
785 class MyValueType
786 {
787 Q_GADGET
788 QML_VALUE_TYPE(myValueType)
789 QML_CONSTRUCTIBLE_VALUE
790 public:
791 Q_INVOKABLE MyValueType(double d);
792
793 // ...
794 };
795 \endcode
796
797 With the above type, the following QML code will produce a \c MyValueType
798 value using the given constructor and assign it to the property.
799
800 \qml
801 QtObject {
802 property myValueType v: 5.4
803 }
804 \endqml
805
806 You can also construct lists of values this way:
807
808 \qml
809 QtObject {
810 property list<myValueType> v: [5.4, 4.5, 3.3]
811 }
812 \endqml
813
814 If you make value types \l{ValueTypeBehavior}{addressable}, you can
815 use such a type in a \l{Type annotations and assertions}{type assertion}
816 to explicitly construct it:
817
818 \qml
819 pragma ValueTypeBehavior: Addressable
820
821 QtObject {
822 function process(d: real) {
823 let v = d as myValueType;
824 // v is a myValueType now, not a number
825 }
826 }
827 \endqml
828
829 \sa QML_VALUE_TYPE
830*/
831
832/*!
833 \macro QML_STRUCTURED_VALUE
834 \since 6.5
835 \relates <qqmlintegration.h>
836
837 Marks the surrounding value type as structured. Structured value types can
838 and will preferably be constructed property-by-property from a JavaScript
839 object. A structured value type, however is always \l QML_CONSTRUCTIBLE_VALUE,
840 too. This means, you can still provide \l Q_INVOKABLE constructors in order to
841 handle construction from primitive types.
842
843 You can declare a structured value type as follows:
844
845 \code
846 class MyValueType
847 {
848 Q_GADGET
849 QML_VALUE_TYPE(myValueType)
850 QML_STRUCTURED_VALUE
851 Q_PROPERTY(double d READ d WRITE setD)
852 Q_PROPERTY(string e READ e WRITE setE)
853
854 // ...
855 };
856 \endcode
857
858 Then you can populate a property of this type as follows:
859
860 \qml
861 QtObject {
862 property myValueType v: ({d: 4.4, e: "a string"})
863 }
864 \endqml
865
866 The extra parentheses are necessary to disambiguate the JavaScript object
867 from what might be interpreted as a JavaScript code block.
868
869 You can also construct lists of values this way:
870
871 \qml
872 QtObject {
873 property list<myValueType> v: [
874 {d: 4.4, e: "a string"},
875 {d: 7.1, e: "another string"}
876 ]
877 }
878 \endqml
879
880 If you make value types \l{ValueTypeBehavior}{addressable}, you can
881 use such a type in a \l{Type annotations and assertions}{type assertion}
882 to explicitly construct it:
883
884 \qml
885 pragma ValueTypeBehavior: Addressable
886
887 QtObject {
888 function process(d: real) {
889 let v = {d: d, e: objectName} as myValueType;
890 // v is a myValueType now
891 }
892 }
893 \endqml
894
895 \sa QML_VALUE_TYPE QML_CONSTRUCTIBLE_VALUE
896*/