diff options
Diffstat (limited to 'src/qml/doc/src/qmlfunctions.qdoc')
-rw-r--r-- | src/qml/doc/src/qmlfunctions.qdoc | 977 |
1 files changed, 895 insertions, 82 deletions
diff --git a/src/qml/doc/src/qmlfunctions.qdoc b/src/qml/doc/src/qmlfunctions.qdoc index b2d322465d..ecb13f160d 100644 --- a/src/qml/doc/src/qmlfunctions.qdoc +++ b/src/qml/doc/src/qmlfunctions.qdoc @@ -1,29 +1,688 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the documentation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:FDL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Free Documentation License Usage -** Alternatively, this file may be used under the terms of the GNU Free -** Documentation License version 1.3 as published by the Free Software -** Foundation and appearing in the file included in the packaging of -** this file. Please review the following information to ensure -** the GNU Free Documentation License version 1.3 requirements -** will be met: https://www.gnu.org/licenses/fdl-1.3.html. -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2017 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only + +/*! + \macro QML_ELEMENT + \relates QQmlEngine + + Declares the enclosing type or namespace to be available in QML, using its + class or namespace name as the QML element name. + + For example, this makes the C++ class \c Slider available as a QML type + named \c Slider. All its properties, invokable methods and enums are exposed. + + \code + class Slider : public QObject + { + Q_OBJECT + QML_ELEMENT + Q_PROPERTY(int value READ value WRITE setValue NOTIFY valueChanged FINAL) + // ... + public: + enum Slippiness { + Dry, Wet, Icy + }; + Q_ENUM(Slippiness) + + Q_INVOKABLE void slide(Slippiness slippiness); + + // ... + } + \endcode + + You can use the build system to register the type in the type namespace + \e {com.mycompany.qmlcomponents} with major version \c 1. + For qmake, specify the following in your project file: + + \badcode + CONFIG += qmltypes + QML_IMPORT_NAME = com.mycompany.qmlcomponents + QML_IMPORT_MAJOR_VERSION = 1 + \endcode + + With CMake, you pass the URI and version to qt_add_qml_module + + \badcode + qt6_add_qml_module(myapp + URI com.mycompany.qmlcomponents + VERSION 1.0 + ) + \endcode + + Once registered, the type can be used in QML by importing the + same type namespace and version number: + + \qml + import com.mycompany.qmlcomponents 1.0 + + Slider { + value: 12 + Component.onCompleted: slide(Slider.Icy) + + // ... + } + \endqml + + You can also make namespaces tagged with Q_NAMESPACE available this way, in + order to expose any enums tagged with Q_ENUM_NS they contain: + + \code + namespace MyNamespace { + Q_NAMESPACE + QML_ELEMENT + + enum MyEnum { + Key1, + Key2, + }; + Q_ENUM_NS(MyEnum) + } + \endcode + + In QML, you can then use the enums: + + \qml + Component.onCompleted: console.log(MyNamespace.Key2) + \endqml + + \b{NOTE:} When classes have the same name but are located in different namespaces using + \l QML_ELEMENT on both of them will cause a conflict. + Make sure to use \l QML_NAMED_ELEMENT() for one of them instead. + + \include {qualified-class-name.qdocinc} {class name must be qualified} + + \sa {Choosing the Correct Integration Method Between C++ and QML}, QML_NAMED_ELEMENT(), + Q_REVISION(), QML_ADDED_IN_VERSION() +*/ + +/*! + \macro QML_NAMED_ELEMENT(name) + \relates QQmlEngine + + Declares the enclosing type or namespace to be available in QML, using \a name + as the element name. Otherwise behaves the same as QML_ELEMENT. + + \code + class SqlEventDatabase : public QObject + { + Q_OBJECT + QML_NAMED_ELEMENT(EventDatabase) + + // ... + }; + \endcode + + \sa {Choosing the Correct Integration Method Between C++ and QML}, QML_ELEMENT +*/ + +/*! + \macro QML_ANONYMOUS + \relates QQmlEngine + + Declares the enclosing type to be available, but anonymous in QML. The type + cannot be created or used to declare properties in QML, but when passed from + C++, it is recognized. In QML, you can use properties of this type if they + are declared in C++. + + \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), QML_INTERFACE +*/ + +/*! + \macro QML_INTERFACE + \relates QQmlEngine + + This macro registers the enclosing C++ type in the QML system as an interface. + + Types registered as an interface in QML should also declare themselves as an + interface with the \l {The Meta-Object System}{meta object system}. For + example: + + \code + struct FooInterface + { + QML_INTERFACE + public: + virtual ~FooInterface(); + virtual void doSomething() = 0; + }; + + Q_DECLARE_INTERFACE(FooInterface, "org.foo.FooInterface") + \endcode + + When registered with QML in this way, they can be used as property types: + + Q_PROPERTY(FooInterface *foo READ foo WRITE setFoo) + + When you assign a \l QObject sub-class to this property, the QML engine does + the interface cast to \c FooInterface* automatically. + + Interface types are implicitly anonymous and uncreatable in QML. + + \b{NOTE:} When inheriting from types using QML_INTERFACE, use \l QML_IMPLEMENTS_INTERFACES + instead of \l Q_INTERFACES. + + \sa QML_IMPLEMENTS_INTERFACES(), QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), QML_ANONYMOUS +*/ + +/*! + \macro QML_IMPLEMENTS_INTERFACES(interfaces) + \relates QQmlEngine + + This macro tells Qt which QML \a interfaces the class implements. + This macro should only be used for interfacing with classes using \l QML_INTERFACE, use \l Q_INTERFACES otherwise. + It's required in order for declarative registration via \l QML_ELEMENT to + function properly. + + \sa QML_INTERFACE, Q_INTERFACES +*/ + +/*! + \macro QML_UNCREATABLE(reason) + \relates QQmlEngine + + Declares that the enclosing type shall not be creatable from QML. This takes + effect if the type is available in QML, by having a \l QML_ELEMENT or + \l QML_NAMED_ELEMENT() macro. The \a reason will be emitted as error message if an + attempt to create the type from QML is detected. + + Some QML types are implicitly uncreatable, in particular types exposed with + \l QML_ANONYMOUS or namespaces exposed with \l QML_ELEMENT or + \l QML_NAMED_ELEMENT(). + + Since Qt 6.0 you can use "" instead of a reason to use a standard message + instead. + + \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_ANONYMOUS +*/ + +/*! + \macro QML_SINGLETON + \relates QQmlEngine + + Declares the enclosing type to be a singleton in QML. This only takes effect + if the type is a \l Q_OBJECT and is available in QML (by having a + \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro). By default, each QQmlEngine + will try to create a singleton instance using either the type's default + constructor or a static factory function of the signature + \c{T *create(QQmlEngine *, QJSEngine *)} when the type is first accessed. + If both do exist and are accessible, the default constructor is preferred. + If there is no default constructor and no factory function the singleton is + inaccessible. The QML engine generally assumes ownership of the singleton and + will delete it when the engine itself is destroyed. You can prevent this by + calling QJSEngine::setObjectOwnership() on the singleton. + + In order to declare a default-constructible class as singleton, all you have + to do is add \l QML_SINGLETON: + + \code + class MySingleton : public QObject + { + Q_OBJECT + QML_ELEMENT + QML_SINGLETON + // Q_PROPERTY( ... ) + public: + // members, Q_INVOKABLE functions, etc. + }; + \endcode + + If the singleton class is not default-constructible, but you can modify it, + you can add a factory function to it, in order to make it accessible: + + \code + class MySingleton : public QObject + { + Q_OBJECT + QML_ELEMENT + QML_SINGLETON + // Q_PROPERTY( ... ) + + public: + static MySingleton *create(QQmlEngine *qmlEngine, QJSEngine *jsEngine) + { + MySingleton *result = nullptr; + // Create the object using some custom constructor or factory. + // The QML engine will assume ownership and delete it, eventually. + return result; + } + + // members, Q_INVOKABLE functions, etc + }; + \endcode + + If you cannot modify the class and it does not have a default constructor or a + suitable factory function, you can provide a \l QML_FOREIGN wrapper to define + the factory function: + + \code + struct SingletonForeign + { + Q_GADGET + QML_FOREIGN(MySingleton) + QML_SINGLETON + QML_NAMED_ELEMENT(MySingleton) + public: + + static MySingleton *create(QQmlEngine *, QJSEngine *engine) + { + MySingleton *result = nullptr; + // Create the instance using some custom constructor or factory. + // The QML engine will assume ownership and delete it, eventually. + return result; + } + }; + \endcode + + Finally, if you want to provide one specific singleton object, the creation of + which you cannot control, you can return that from a factory function. This is + a replacement for the \l qmlRegisterSingletonInstance function. + If you were calling + + \code + qmlRegisterSingletonInstance("MyModule", 1, 0, "MySingleton", myObject); + \endcode + + with myObject being of type \c{MySingleton *}, you can do the following + instead: + + \code + struct SingletonForeign + { + Q_GADGET + QML_FOREIGN(MySingleton) + QML_SINGLETON + QML_NAMED_ELEMENT(MySingleton) + public: + + // Initialize this using myObject where you would previously + // call qmlRegisterSingletonInstance(). + inline static MySingleton *s_singletonInstance = nullptr; + + static MySingleton *create(QQmlEngine *, QJSEngine *engine) + { + // The instance has to exist before it is used. We cannot replace it. + Q_ASSERT(s_singletonInstance); + + // The engine has to have the same thread affinity as the singleton. + Q_ASSERT(engine->thread() == s_singletonInstance->thread()); + + // There can only be one engine accessing the singleton. + if (s_engine) + Q_ASSERT(engine == s_engine); + else + s_engine = engine; + + // Explicitly specify C++ ownership so that the engine doesn't delete + // the instance. + QJSEngine::setObjectOwnership(s_singletonInstance, + QJSEngine::CppOwnership); + return s_singletonInstance; + } + + private: + inline static QJSEngine *s_engine = nullptr; + }; + \endcode + + This way, the pre-existing class \c MySingleton is declared to be a QML + singleton, called \c MySingleton. You can specify an instance for it any time + before it is used by setting the \c s_singletonInstance member. None of this + requires modification of \c MySingleton itself. + + \note This pattern doesn't work if either the singleton is accessed by + multiple QML engines, or if the QML engine accessing it has a different thread + affinity than the singleton object itself. As shown above, you can check the + parameters to the \c create() method for identity and thread affinity of the + engine in order to assert on that. + + \sa QML_ELEMENT, QML_NAMED_ELEMENT(), + qmlRegisterSingletonInstance(), QQmlEngine::singletonInstance(), {Singletons in QML} +*/ + +/*! + \macro QML_ADDED_IN_VERSION(MAJOR, MINOR) + \relates QQmlEngine + + Declares that the enclosing type or namespace was added in the specified + \a{MAJOR}.\a{MINOR} version. The version is assumed to be in line with any + revisions given by \l Q_REVISION() macros on methods, slots, or signals, + and any REVISION() attributes on properties declared with \l Q_PROPERTY(). + + \l QML_ADDED_IN_VERSION() only takes effect if the type or namespace is + available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(), + \l QML_ANONYMOUS, or \l QML_INTERFACE macro. + + If the QML module the type belongs to is imported with a lower version than + the one determined this way, the QML type is invisible. + + \sa QML_ELEMENT, QML_NAMED_ELEMENT +*/ + +/*! + \macro QML_ADDED_IN_MINOR_VERSION(VERSION) + \relates QQmlEngine + \deprecated [6.7] Use QML_ADDED_IN_VERSION and specify the full version + + Declares that the enclosing type or namespace was added in the specified minor + \a VERSION, relative to the module major version. The minor version is assumed + to be in line with any revisions given by \l Q_REVISION() macros on methods, + slots, or signals, and any REVISION() attributes on properties declared with + \l Q_PROPERTY(). + + \l QML_ADDED_IN_MINOR_VERSION() only takes effect if the type or namespace is + available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(), + \l QML_ANONYMOUS, or \l QML_INTERFACE macro. + + If the QML module the type belongs to is imported with a lower version than + the one determined this way, the QML type is invisible. + + \sa QML_ADDED_IN_VERSION, QML_ELEMENT, QML_NAMED_ELEMENT +*/ + +/*! + \macro QML_REMOVED_IN_VERSION(MAJOR, MINOR) + \relates QQmlEngine + + Declares that the enclosing type or namespace was removed in the specified + \a{MAJOR}.\a{MINOR} version. This is primarily useful when replacing the + implementation of a QML type. If a corresponding \l QML_ADDED_IN_VERSION() + is present on a different type or namespace of the same QML name, then the + removed type is used when importing versions of the module lower than + \a{MAJOR}.\a{MINOR}, and the added type is used when importing + versions of the module greater or equal \a{MAJOR}.\a{MINOR}. + + \l QML_REMOVED_IN_VERSION() only takes effect if type or namespace is + available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(), + \l QML_ANONYMOUS, or \l QML_INTERFACE macro. + + \sa QML_ELEMENT, QML_NAMED_ELEMENT +*/ + +/*! + \macro QML_REMOVED_IN_MINOR_VERSION(VERSION) + \relates QQmlEngine + \deprecated [6.7] Use QML_REMOVED_IN_VERSION and specify the full version + + Declares that the enclosing type or namespace was removed in the specified + minor \a VERSION, relative to the module major version. This is primarily + useful when replacing the implementation of a QML type. If a corresponding + \l QML_ADDED_IN_VERSION() is present on a different type or namespace of + the same QML name, then the removed type is used when importing versions of + the module lower than \a VERSION, and the added type is used when importing + versions of the module greater or equal \a VERSION. + + \l QML_REMOVED_IN_MINOR_VERSION() only takes effect if type or namespace is + available in QML, by having a \l QML_ELEMENT, \l QML_NAMED_ELEMENT(), + \l QML_ANONYMOUS, or \l QML_INTERFACE macro. + + \sa QML_REMOVED_IN_VERSION, QML_ELEMENT, QML_NAMED_ELEMENT +*/ + +/*! + \macro QML_EXTRA_VERSION(MAJOR, MINOR) + \relates QQmlEngine + + Declare that the type should also be available in version \a{MAJOR}.\a{MINOR}. + This can be helpful if a type should be available in multiple major versions. + + Types are automatically registered for: + \list + \li The major version they were introduced in, see \l{QML_ADDED_IN_VERSION}. + \li Any major versions any their members were introduced in. + \li The current major version of their module, unless they were + \l{QML_REMOVED_IN_VERSION} before that. + \endlist + + Notably, they are not automatically registered in any \l{PAST_MAJOR_VERSIONS} + between the above. You can use QML_EXTRA_VERSION to manually register your + types in further major versions. + + \note Keeping multiple \l{PAST_MAJOR_VERSIONS} around is computationally + expensive. + + \sa QML_ELEMENT, QML_ADDED_IN_VERSION +*/ + +/*! + \macro QML_ATTACHED(ATTACHED_TYPE) + \relates QQmlEngine + + Declares that the enclosing type attaches \a ATTACHED_TYPE as an + \l {Attached Properties and Attached Signal Handlers} + {attached property} to other types. This takes effect if the type + is exposed to QML using a \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro. + + \include {qualified-class-name.qdocinc} {class name must be qualified} + + \sa QML_ELEMENT, QML_NAMED_ELEMENT(), qmlAttachedPropertiesObject(), + {Providing Attached Properties} +*/ + +/*! + \macro QML_EXTENDED(EXTENDED_TYPE) + \relates QQmlEngine + + Declares that the enclosing type uses \a EXTENDED_TYPE as an extension to + provide further properties, methods, and enumerations in QML. This takes + effect if the type is exposed to QML using a \l QML_ELEMENT or + \l QML_NAMED_ELEMENT() macro. + + \warning Members of \a EXTENDED_TYPE are implicitly treated as FINAL. + + \include {qualified-class-name.qdocinc} {class name must be qualified} + + \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED_NAMESPACE(), + {Registering Extension Objects} +*/ + +/*! + \macro QML_EXTENDED_NAMESPACE(EXTENDED_NAMESPACE) + \relates QQmlEngine + + Declares that the enclosing type uses \a EXTENDED_NAMESPACE as an extension to + provide further enumerations in QML. This takes effect if the type + is exposed to QML using a \l QML_ELEMENT or \l QML_NAMED_ELEMENT() macro. + The enumerations need to be exposed to the metaobject system for this to work. + + For example, give the following C++ code + \code + namespace MyNamespace { + Q_NAMESPACE + enum MyEnum { MyEnumerator = 10 }; + Q_ENUM_NS(MyEnum) + } + + class QmlType : public QObject + { + Q_OBJECT + QML_ELEMENT + QML_EXTENDED_NAMESPACE(MyNamespace) + } + \endcode + + we can access the enum in QML: + \qml + QmlType { + property int i: QmlType.MyEnumerator // i will be 10 + } + \endqml + + \note EXTENDED_NAMESPACE can also be a QObject or QGadget; in that case - and in contrast to + QML_EXTENDED, which also exposes methods and properties - only its enumerations + are exposed. + + \note \a EXTENDED_NAMESPACE must have a metaobject; i.e. it must either be a namespace which + contains the Q_NAMESPACE macro or a QObject/QGadget. + + \include {qualified-class-name.qdocinc} {class name must be qualified} + + \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED(), + {Registering Extension Objects}, Q_ENUM, Q_ENUM_NS +*/ + +/*! + \macro QML_FOREIGN(FOREIGN_TYPE) + \relates QQmlEngine + + Declares that any \l QML_ELEMENT, \l QML_NAMED_ELEMENT(), \l QML_ANONYMOUS, + \l QML_INTERFACE, \l QML_UNCREATABLE(), \l QML_SINGLETON, + \l QML_ADDED_IN_VERSION(), \l QML_REMOVED_IN_VERSION(), + \l QML_ADDED_IN_MINOR_VERSION(), \l QML_REMOVED_IN_MINOR_VERSION(), + \l QML_EXTENDED(), or \l QML_EXTENDED_NAMESPACE() macros + in the enclosing C++ type do not apply to the enclosing type but instead to + \a FOREIGN_TYPE. The enclosing type still needs to be registered with the + \l {The Meta-Object System}{meta object system} using a \l Q_GADGET or + \l Q_OBJECT macro. + + This is useful for registering types that cannot be amended to add the macros, + for example because they belong to 3rdparty libraries. + To register a namespace, see \l QML_FOREIGN_NAMESPACE(). + + \note You may want to use \l QML_NAMED_ELEMENT() instead of \l QML_ELEMENT. + With QML_ELEMENT, the element is named after the struct it is contained in, + not the foreign type. The \l {Foreign objects integration} chapter in + \l {Writing advanced QML Extensions with C++} demonstrates this. + + \note QML_ATTACHED() can currently not be redirected like this. It has to be + specificed in the same type that implements qmlAttachedProperties(). + + \include {qualified-class-name.qdocinc} {class name must be qualified} + + \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_FOREIGN_NAMESPACE() +*/ + +/*! + \macro QML_FOREIGN_NAMESPACE(FOREIGN_NAMESPACE) + \relates QQmlEngine + + Declares that any \l QML_ELEMENT, \l QML_NAMED_ELEMENT(), \l QML_ANONYMOUS, + \l QML_INTERFACE, \l QML_UNCREATABLE(), \l QML_SINGLETON, + \l QML_ADDED_IN_VERSION(), \l QML_REMOVED_IN_VERSION(), + \l QML_ADDED_IN_MINOR_VERSION(), or \l QML_REMOVED_IN_MINOR_VERSION() + macros in the enclosing C++ namespace do not apply to the enclosing type but + instead to \a FOREIGN_NAMESPACE. The enclosing namespace still needs to be + registered with the \l {The Meta-Object System}{meta object system} using a + \l Q_NAMESPACE macro. + + This is useful for registering namespaces that cannot be amended to add the macros, + for example because they belong to 3rdparty libraries. + + \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_FOREIGN() +*/ + +/*! + \macro QML_UNAVAILABLE + \relates QQmlEngine + + This macro declares the enclosing type to be unavailable in QML. It registers + an internal dummy type called \c QQmlTypeNotAvailable as \l QML_FOREIGN() + type, using any further QML macros you specify. + + Normally, the types exported by a module should be fixed. However, if a C++ + type is not available, you should at least "reserve" the QML type name, and + give the user of the unavailable type a meaningful error message. + + Example: + + \code + #ifdef NO_GAMES_ALLOWED + struct MinehuntGame + { + Q_GADGET + QML_NAMED_ELEMENT(Game) + QML_UNAVAILABLE + QML_UNCREATABLE("Get back to work, slacker!"); + }; + #else + class MinehuntGame : public QObject + { + Q_OBJECT + QML_NAMED_ELEMENT(Game) + // ... + }; + #endif + \endcode + + This will cause any QML which attempts to use the "Game" type to produce an + error message: + + \badcode + fun.qml: Get back to work, slacker! + Game { + ^ + \endcode + + Using this technique, you only need a \l Q_GADGET struct to customize the error + message, not a full-blown \l QObject. Without \l QML_UNCREATABLE(), + \l QML_UNAVAILABLE still results in a more specific error message than the usual + "is not a type" for completely unknown types. + + \include {qualified-class-name.qdocinc} {class name must be qualified} + + \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE(), QML_FOREIGN() +*/ + +/*! + \macro QML_SEQUENTIAL_CONTAINER(VALUE_TYPE) + \relates QQmlEngine + + This macro declares the enclosing or referenced type as a sequential container + managing a sequence of \a VALUE_TYPE elements. \a VALUE_TYPE can be an actual + \l{QML Value Types}{value type} or a pointer to an + \l{QML Object Types}{object type}. You will rarely be able to add this macro + to the actual container declaration since containers are usually templates. + You should use \l{QML_FOREIGN} to attach the type registration to a template + instantiation. Using this technique you can, for example, declare sequential + containers like this: + + \code + class IntDequeRegistration + { + Q_GADGET + QML_FOREIGN(std::deque<int>) + QML_ANONYMOUS + QML_SEQUENTIAL_CONTAINER(int) + }; + \endcode + + After this, you can use the container like a JavaScript array in QML. + + \code + class Maze + { + Q_OBJECT + Q_ELEMENT + // 0: North, 1: East, 2: South, 3: West + Q_PROPERTY(std::deque<int> solution READ solution CONSTANT FINAL) + [...] + } + \endcode + + \code + Item { + Maze { + id: maze + } + + function showSolution() { + maze.solution.forEach([...]) + } + } + \endcode + + \note For \l{QML Value Types} \l{QList} is automatically registered as + sequential container. For \l{QML Object Types} \l{QQmlListProperty} is. + You don't have to add these registrations. + + \note You cannot currently give the container a custom name. Any argument + passed to \l{QML_NAMED_ELEMENT} is ignored. The automatically registered + sequential containers are available under the familiar \e{list<...>} names, + for example \e{list<QtObject>} or \e{list<font>}. + + \include {qualified-class-name.qdocinc} {class name must be qualified} + + \sa QML_ANONYMOUS, QML_FOREIGN() +*/ /*! \macro QML_DECLARE_TYPE() @@ -41,7 +700,8 @@ Current the only supported type info is \c QML_HAS_ATTACHED_PROPERTIES which declares that the \a Type supports \l {Attached Properties and Attached Signal Handlers} - {attached properties}. + {attached properties}. QML_DECLARE_TYPEINFO() is not necessary if \a Type contains the + QML_ATTACHED macro. */ /*! @@ -58,7 +718,7 @@ /*! - \fn int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) + \fn template <typename T> int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) \relates QQmlEngine This template function registers the C++ type in the QML system with @@ -106,11 +766,12 @@ QML written to previous versions to continue to work, even if more advanced versions of some of its types are available. - \sa {Choosing the Correct Integration Method Between C++ and QML} + \sa QML_ELEMENT, QML_NAMED_ELEMENT(), + {Choosing the Correct Integration Method Between C++ and QML} */ /*! - \fn int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) + \fn template<typename T, int metaObjectRevision> int qmlRegisterRevision(const char *uri, int versionMajor, int versionMinor) \relates QQmlEngine This template function registers the specified revision of a C++ type in the QML system with @@ -129,7 +790,7 @@ */ /*! - \fn int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message) + \fn template <typename T> int qmlRegisterUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& message) \relates QQmlEngine This template function registers the C++ type in the QML system with @@ -143,12 +804,12 @@ Returns the QML type id. - \sa qmlRegisterTypeNotAvailable(), + \sa QML_UNCREATABLE(), qmlRegisterTypeNotAvailable(), {Choosing the Correct Integration Method Between C++ and QML} */ /*! - \fn int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) + \fn template <typename T, typename E> int qmlRegisterExtendedType(const char *uri, int versionMajor, int versionMinor, const char *qmlName) \relates QQmlEngine This template function registers the C++ type and its extension object in the @@ -158,12 +819,12 @@ Returns the QML type id. - \sa qmlRegisterType(), {Registering Extension Objects} + \sa QML_EXTENDED(), qmlRegisterType(), {Registering Extension Objects} */ /*! - \fn int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason) + \fn template <typename T, typename E> int qmlRegisterExtendedUncreatableType(const char *uri, int versionMajor, int versionMinor, const char *qmlName, const QString& reason) \relates QQmlEngine This template function registers the C++ type and its extension @@ -180,7 +841,7 @@ Returns the QML type id. - \sa qmlRegisterUncreatableType() + \sa QML_EXTENDED(), QML_UNCREATABLE(), qmlRegisterUncreatableType() */ /*! @@ -209,7 +870,7 @@ Key1, Key2, }; - Q_ENUMS(MyEnum) + Q_ENUM_NS(MyEnum) } //... @@ -220,6 +881,8 @@ \code Component.onCompleted: console.log(MyNamespace.Key2) \endcode + + \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_UNCREATABLE() */ /*! @@ -235,6 +898,8 @@ the \a parser provided. Returns the QML type id. + + \sa QML_ELEMENT, QML_NAMED_ELEMENT(), QML_EXTENDED() */ /*! @@ -269,12 +934,13 @@ Without this, a generic "Game is not a type" message would be given. - \sa qmlRegisterUncreatableType(), + \sa QML_UNAVAILABLE, qmlRegisterUncreatableType(), {Choosing the Correct Integration Method Between C++ and QML} */ /*! - \fn int qmlRegisterAnonymousType(const char *uri, int versionMajor) + \fn template <typename T> int qmlRegisterAnonymousType(const char *uri, int versionMajor) + \relates QQmlEngine This template function registers the C++ type in the QML system as an anonymous type. The resulting QML type does not have a name. Therefore, instances of this type cannot be created from @@ -352,17 +1018,7 @@ Returns the QML type id. \since 5.14 - \sa {Choosing the Correct Integration Method Between C++ and QML} -*/ - -/*! - \fn int qmlRegisterType() - \relates QQmlEngine - \overload - \deprecated - - Do not use this function. For anonymous type registrations, use \l qmlRegisterAnonymousType(), - and make sure to provide a URI and a major version. + \sa QML_ANONYMOUS, {Choosing the Correct Integration Method Between C++ and QML} */ /*! @@ -396,10 +1052,12 @@ the interface cast to \c FooInterface* automatically. Returns the QML type id. + + \sa QML_INTERFACE */ /*! - \fn int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, QJSValue (*callback)(QQmlEngine *, QJSEngine *)) + \fn int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, std::function<QJSValue(QQmlEngine *, QJSEngine *)> callback) \relates QQmlEngine This function may be used to register a singleton type provider \a callback in a particular \a uri @@ -454,7 +1112,7 @@ } \endqml - \sa {Choosing the Correct Integration Method Between C++ and QML} + \sa QML_SINGLETON, {Choosing the Correct Integration Method Between C++ and QML} */ /*! @@ -473,15 +1131,24 @@ If \a create is true and type \e T is a valid attaching type, this creates and returns a new attached object instance. - Returns 0 if type \e T is not a valid attaching type, or if \a create is false and no + Returns \nullptr if type \e T is not a valid attaching type, or if \a create is false and no attachment object instance has previously been created for \a attachee. - \sa {Providing Attached Properties} + \sa QML_ATTACHED(), {Providing Attached Properties} +*/ +/*! + \fn QObject *qmlExtendedObject(const QObject *base) + \relates QQmlEngine + + This function returns the extension object that belongs to \a base, if there is any. + Otherwise it returns \c nullptr. + + \sa QML_EXTENDED */ /*! - \fn int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *(*callback)(QQmlEngine *, QJSEngine *)) + \fn template <typename T> int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, std::function<QObject*(QQmlEngine *, QJSEngine *)> callback) \relates QQmlEngine This function may be used to register a singleton type provider \a callback in a particular \a uri @@ -511,7 +1178,7 @@ Q_PROPERTY (int someProperty READ someProperty WRITE setSomeProperty NOTIFY somePropertyChanged) public: - SingletonTypeExample(QObject* parent = 0) + SingletonTypeExample(QObject *parent = nullptr) : QObject(parent), m_someProperty(0) { } @@ -570,15 +1237,7 @@ } \endqml - \sa {Choosing the Correct Integration Method Between C++ and QML} -*/ - - -/*! - \fn int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, std::function<QObject*(QQmlEngine *, QJSEngine *)> callback) - \relates QQmlEngine - - \overload qmlRegisterSingletonType + \sa QML_SINGLETON, {Choosing the Correct Integration Method Between C++ and QML} */ /*! @@ -625,10 +1284,12 @@ That can be done by adding a pragma Singleton statement among the imports of the type's QML file. In addition the type must be defined in a qmldir file with a singleton keyword and the qmldir must be imported by the QML files using the singleton. + + \sa QML_SINGLETON */ /*! - \fn int qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject* cppObject) + \fn int qmlRegisterSingletonInstance(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *cppObject) \relates QQmlEngine \since 5.14 @@ -656,6 +1317,8 @@ \l {qmlRegisterSingletonType}. See \l{Threads and QObjects} for more information about thread safety. + \b{NOTE:} qmlRegisterSingleton can only be used when all types of that module are registered procedurally. + Usage: \code // First, define your QObject which provides the functionality. @@ -717,7 +1380,7 @@ } \endqml - \sa qmlRegisterSingletonType + \sa QML_SINGLETON, qmlRegisterSingletonType */ /*! @@ -738,20 +1401,25 @@ \fn bool qmlProtectModule(const char* uri, int majVersion); \relates QQmlEngine - This function protects a module from having types registered into it. This - can be used to prevent other plugins from injecting types into your module. - It can also be a performance improvement, as it allows the engine to skip - checking for the possibility of new types or plugins when this import is - reached. - - The performance benefit is primarily seen when registering application - specific types from within the application instead of through a plugin. - Using qmlProtectModule allows the engine to skip checking for a plugin when - that uri is imported, which can be noticeable with slow file systems. - - After this function is called, any attempt to register C++ types into this - uri, major version combination will lead to a runtime error. Call this after - you have registered all of your types with the engine. + This function protects a module from further modification. This can be used + to prevent other plugins from injecting types into your module. It can also + be a performance improvement, as it allows the engine to skip checking for + the possibility of new types or plugins when this import is reached. + + Once qmlProtectModule has been called, a QML engine will not search for a new + \c qmldir file to load the module anymore. It will re-use any \c qmldir files + it has loaded before, though. Therefore, types present at this point continue + to work. Mind that different QML engines may load different modules. The + module protection, however, is global and affects all engines. The overhead + of locating \c qmldir files and loading plugins may be noticeable with slow file + systems. Therefore, protecting a module once you are sure you won't need to + load it anymore can be a good optimization. Mind also that the module lock + not only affects plugins but also any other qmldir directives, like \c import + or \c prefer, as well as any composite types or scripts declared in a \c qmldir + file. + + In addition, after this function is called, any attempt to register C++ types + into this uri, major version combination will lead to a runtime error. Returns true if the module with \a uri as a \l{Identified Modules} {module identifier} and \a majVersion as a major version number was found @@ -791,5 +1459,150 @@ Returns -1 if no matching type was found or one of the given parameters was invalid. - \sa qmlRegisterType(), qmlRegisterSingletonType() + \sa QML_ELEMENT, QML_NAMED_ELEMENT, QML_SINGLETON, qmlRegisterType(), qmlRegisterSingletonType() +*/ + +/*! + \macro QML_VALUE_TYPE(name) + \relates QQmlEngine + + Declares the enclosing type or namespace to be available in QML, using \a name + as the name. The type has to be a value type and the name has to be lower case. + + \code + class MyValueType + { + Q_GADGET + QML_VALUE_TYPE(myValueType) + + // ... + }; + \endcode + + \sa {Choosing the Correct Integration Method Between C++ and QML}, QML_NAMED_ELEMENT +*/ + +/*! + \macro QML_CONSTRUCTIBLE_VALUE + \since 6.5 + \relates QQmlEngine + + Marks the surrounding value type as constructible. That is, any \l Q_INVOKABLE + constructors of the type that take exactly one argument can be used when + assigning a JavaScript value to a property of this type. + + You can declare a constructible value type as follows: + + \code + class MyValueType + { + Q_GADGET + QML_VALUE_TYPE(myValueType) + QML_CONSTRUCTIBLE_VALUE + public: + Q_INVOKABLE MyValueType(double d); + + // ... + }; + \endcode + + With the above type, the following QML code will produce a \c MyValueType + value using the given constructor and assign it to the property. + + \qml + QtObject { + property myValueType v: 5.4 + } + \endqml + + You can also construct lists of values this way: + + \qml + QtObject { + property list<myValueType> v: [5.4, 4.5, 3.3] + } + \endqml + + If you make value types \l{ValueTypeBehavior}{addressable}, you can + use such a type in a \l{Type annotations and assertions}{type assertion} + to explicitly construct it: + + \qml + pragma ValueTypeBehavior: Addressable + + QtObject { + function process(d: real) { + let v = d as myValueType; + // v is a myValueType now, not a number + } + } + \endqml + + \sa QML_VALUE_TYPE +*/ + +/*! + \macro QML_STRUCTURED_VALUE + \since 6.5 + \relates QQmlEngine + + Marks the surrounding value type as structured. Structured value types can + and will preferably be constructed property-by-property from a JavaScript + object. A structured value type, however is always \l QML_CONSTRUCTIBLE_VALUE, + too. This means, you can still provide \l Q_INVOKABLE constructors in order to + handle construction from primitive types. + + You can declare a structured value type as follows: + + \code + class MyValueType + { + Q_GADGET + QML_VALUE_TYPE(myValueType) + QML_STRUCTURED_VALUE + Q_PROPERTY(double d READ d WRITE setD) + Q_PROPERTY(string e READ e WRITE setE) + + // ... + }; + \endcode + + Then you can populate a property of this type as follows: + + \qml + QtObject { + property myValueType v: ({d: 4.4, e: "a string"}) + } + \endqml + + The extra parentheses are necessary to disambiguate the JavaScript object + from what might be interpreted as a JavaScript code block. + + You can also construct lists of values this way: + + \qml + QtObject { + property list<myValueType> v: [ + {d: 4.4, e: "a string"}, + {d: 7.1, e: "another string"} + ] + } + \endqml + + If you make value types \l{ValueTypeBehavior}{addressable}, you can + use such a type in a \l{Type annotations and assertions}{type assertion} + to explicitly construct it: + + \qml + pragma ValueTypeBehavior: Addressable + + QtObject { + function process(d: real) { + let v = {d: d, e: objectName} as myValueType; + // v is a myValueType now + } + } + \endqml + + \sa QML_VALUE_TYPE QML_CONSTRUCTIBLE_VALUE */ |