2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
3/*!
4\page qtqml-cppintegration-data.html
5\title Data Type Conversion Between QML and C++
6\brief Description of how data types are exchanged between QML and C++
7
8When data values are exchanged between QML and C++, they are converted by the
9QML engine to have the correct data types as appropriate for use in QML or
10C++. This requires the exchanged data to be of a type that is recognizable by
11the engine.
12
13The QML engine provides built-in support for a large number of Qt C++ data
14types. Additionally, custom C++ types may be registered with the QML type
15system to make them available to the engine.
16
17For more information about C++ and the different QML integration methods,
18see the
19\l {Overview - QML and C++ Integration} {C++ and QML integration overview} page.
20
21This page discusses the data types supported by the QML engine and how
22they are converted between QML and C++.
23
24
25\section1 Data Ownership
26
27When data is transferred from C++ to QML, the ownership of the data always
28remains with C++. The exception to this rule is when a QObject is returned from
29an explicit C++ method call: in this case, the QML engine assumes ownership of
30the object, unless the ownership of the object has explicitly been set to
31remain with C++ by invoking QQmlEngine::setObjectOwnership() with
32QQmlEngine::CppOwnership specified.
33
34Additionally, the QML engine respects the normal QObject parent ownership
35semantics of Qt C++ objects, and will never delete a QObject instance which
36has a parent.
37
38
39\section1 Basic Qt Data Types
40
41By default, QML recognizes the following Qt data types, which are
42automatically converted to a corresponding \l {QML Value Types}{QML value type}
43when passed from C++ to QML and vice-versa:
44
45\table
46 \row
47 \li Qt Type
48 \li QML Value Type
49 \row
50 \li bool
51 \li \l bool
52 \row
53 \li unsigned int, int
54 \li \l int
55 \row
56 \li double
57 \li \l double
58 \row
59 \li float, qreal
60 \li \l real
61 \row
62 \li QString
63 \li \l string
64 \row
65 \li QUrl
66 \li \l url
67 \row
68 \li QColor
69 \li \l color
70 \row
71 \li QFont
72 \li \l font
73 \row
74 \li QDateTime
75 \li \l date
76 \row
77 \li QPoint, QPointF
78 \li \l point
79 \row
80 \li QSize, QSizeF
81 \li \l size
82 \row
83 \li QRect, QRectF
84 \li \l rect
85 \row
86 \li QMatrix4x4
87 \li \l matrix4x4
88 \row
89 \li QQuaternion
90 \li \l quaternion
91 \row
92 \li QVector2D, QVector3D, QVector4D
93 \li \l vector2d, \l vector3d, \l vector4d
94\endtable
95
96\note Classes provided by the \l {Qt GUI} module, such as QColor, QFont,
97QQuaternion and QMatrix4x4, are only available from QML when the \l {Qt Quick}
98module is included.
99
100As a convenience, many of these types can be specified in QML by string values,
101or by a related method provided by the \l {QtQml::Qt} object. For example, the \l
102{Image::sourceSize} property is of type \l size (which automatically translates
103to the QSize type) and can be specified by a string value formatted as
104"width\c{x}height", or by the Qt.size() function:
105
106\qml
107Item {
108 Image { sourceSize: "100x200" }
109 Image { sourceSize: Qt.size(100, 200) }
110}
111\endqml
112
113See documentation for each individual type under \l {QML Value Types} for more
114information.
115
116
117\section1 QObject-derived Types
118
119Any QObject-derived class may be used as a type for the exchange of data between
120QML and C++, providing the class has been registered with the QML type system.
121
122The engine allows the registration of both instantiable and non-instantiable
123types. Once a class is registered as a QML type, it can be used as a data type
124for exchanging data between QML and C++. See
125\l{qtqml-cppintegration-definetypes.html#registering-c++-types-with-the-qml-type-system}{Registering C++ types with the QML type system} for further details on type registration.
126
127
128\section1 Conversion Between Qt and JavaScript Types
129
130The QML engine has built-in support for converting a number of Qt types to
131related JavaScript types, and vice-versa, when transferring data between QML
132and C++. This makes it possible to use these types and receive them in C++ or
133JavaScript without needing to implement custom types that provide access to
134the data values and their attributes.
135
136(Note that the JavaScript environment in QML modifies native JavaScript object
137prototypes, including those of \c String, \c Date and \c Number, to provide
138additional features. See the \l {qtqml-javascript-hostenvironment.html}
139{JavaScript Host Environment} for further details.)
140
141
142\section2 QVariantList and QVariantMap to JavaScript Array-like and Object
143
144The QML engine provides automatic type conversion between QVariantList and
145JavaScript array-likes, and between QVariantMap and JavaScript objects.
146
147An \e{array-like}, in ECMAScript terms, is an object used like an array. The
148array-likes produced by conversion from QVariantList (and other C++ sequential
149containers) are not only that but also offer the common array methods
150and automatically synchronize the \e length property. They can be used just
151like JavaScript Arrays for any practical purposes. The \e{Array.isArray()}
152method still returns false for them, though.
153
154For example, the function defined in QML below expects two arguments, an
155array and an object, and prints their contents using the standard JavaScript
156syntax for array and object item access. The C++ code below calls this
157function, passing a QVariantList and a QVariantMap, which are automatically
158converted to JavaScript array-like and object values, respectively:
339The usual pattern is to use a gadget class as the type of a property, or to
340emit a gadget as a signal argument. In such cases, the gadget instance is
341passed by value between C++ and QML (because it's a value type). If QML code
342changes a property of a gadget property, the entire gadget is re-created and
343passed back to the C++ property setter. In Qt 5, gadget types cannot be
344instantiated by direct declaration in QML. In contrast, a QObject instance can
345be declared; and QObject instances are always passed by pointer from C++ to QML.
346
347\section1 Enumeration Types
348
349To use a custom enumeration as a data type, its class must be registered and
350the enumeration must also be declared with Q_ENUM() to register it with Qt's
351meta object system. For example, the \c Message class below has a \c Status
352enum:
353
354\code
355 class Message : public QObject
356 {
357 Q_OBJECT
358 Q_PROPERTY(Status status READ status NOTIFY statusChanged)
359 public:
360 enum Status {
361 Ready,
362 Loading,
363 Error
364 };
365 Q_ENUM(Status)
366 Status status() const;
367 signals:
368 void statusChanged();
369 };
370\endcode
371
372Providing the \c Message class has been
373\l{qtqml-cppintegration-definetypes.html#registering-c++-types-with-the-qml-type-system}{registered} with the QML type system, its \c Status enum can be used from QML:
374
375\qml
376Message {
377 onStatusChanged: {
378 if (status == Message.Ready)
379 console.log("Message is loaded!")
380 }
381 }
382\endqml
383
384To use an enum as a \l {QFlags}{flags} type in QML, see \l Q_FLAG().
385
386\note The names of enum values must begin with a capital letter in order to
387be accessible from QML.
388
389\code
390...
391enum class Status {
392 Ready,
393 Loading,
394 Error
395}
396Q_ENUM(Status)
397...
398\endcode
399
400Enum classes are registered in QML as scoped and unscoped properties.
401The \c Ready value will be registered as \c Message.Status.Ready and \c Message.Ready .
402
403When using enum classes, there can be multiple enums using the same identifiers.
404The unscoped registration will be overwriten by the last registered enum. For classes
405that contain such name conficts it is possible to disable the unscoped registration by
406annotating your class with a special Q_CLASSINFO macro.
407Use the name \c RegisterEnumClassesUnscoped with the value \c false to prevent scoped
408enums from being merged into the same name space.