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
*/
qtdeclarative
src
qml
doc
src
cppintegration
macros.qdoc
Generated on
for Qt by
1.14.0