aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/doc/src/cppintegration/exposecppattributes.qdoc
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/doc/src/cppintegration/exposecppattributes.qdoc')
-rw-r--r--src/qml/doc/src/cppintegration/exposecppattributes.qdoc142
1 files changed, 99 insertions, 43 deletions
diff --git a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc
index 618ed1e334..6031d0eebb 100644
--- a/src/qml/doc/src/cppintegration/exposecppattributes.qdoc
+++ b/src/qml/doc/src/cppintegration/exposecppattributes.qdoc
@@ -1,29 +1,5 @@
-/****************************************************************************
-**
-** 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
/*!
\page qtqml-cppintegration-exposecppattributes.html
\title Exposing Attributes of C++ Types to QML
@@ -32,9 +8,9 @@
QML can easily be extended with functionality defined in C++ code. Due to the
tight integration of the QML engine with the \l{The Meta-Object System}{Qt
meta-object system}, any functionality that is appropriately exposed by a
-QObject-derived class is accessible from QML code. This enables C++ data and
-functions to be accessible directly from QML, often with little or no
-modification.
+QObject-derived class or a Q_GADGET type is accessible from QML code. This
+enables C++ data and functions to be accessible directly from QML, often with
+little or no modification.
The QML engine has the ability to introspect QObject instances through the
meta-object system. This means any QML code can access the following members of
@@ -46,7 +22,7 @@ an instance of a QObject-derived class:
\li Signals
\endlist
-(Additionally, enums are available if they have been declared with Q_ENUMS.
+(Additionally, enums are available if they have been declared with Q_ENUM.
See \l{qtqml-cppintegration-data.html}{Data Type Conversion Between QML and C++}
for more details.)
@@ -56,11 +32,27 @@ system}{registered with the QML type system}. However, if a class is to be
used in a way that requires the engine to access additional type information
— for example, if the class itself is to be used as a method parameter or
property, or if one of its enum types is to be used in this way — then the
-class may need to be registered.
+class may need to be registered. Registration is recommended for all types you
+use in QML, as only registered types can be analyzed at compile time.
+
+Registration is required for Q_GADGET types, as they don't derive from a known
+common base and can't be made available automatically. Without registration,
+their properties and methods are inaccessible.
+
+You can make C++ types from a different module available in your own module by
+adding a dependency to your \l{qt_add_qml_module} call using the \e DEPENDENCIES
+option. You may, for example, want to depend on QtQuick so that your QML-exposed
+C++ types can use \l QColor as method arguments and return values. QtQuick
+exposes \l QColor as a \l {QML Value Types}{value type} \e color. Such
+dependencies may be automatically inferred at run time, but you should not rely
+on this.
Also note that a number of the important concepts covered in this document are
demonstrated in the \l{Writing QML Extensions with C++} tutorial.
+For more information about C++ and the different QML integration methods,
+see the
+\l {Overview - QML and C++ Integration} {C++ and QML integration overview} page.
\section1 Data Type Handling and Ownership
@@ -85,7 +77,7 @@ A \e property can be specified for any QObject-derived class using the
Q_PROPERTY() macro. A property is a class data member with an associated read
function and optional write function.
-All properties of a QObject-derived class are accessible from QML.
+All properties of a QObject-derived or Q_GADGET class are accessible from QML.
For example, below is a \c Message class with an \c author property. As
specified by the Q_PROPERTY macro call, this property is readable through
@@ -99,7 +91,8 @@ Instead of:
\badcode
using FooEnum = Foo::Enum;
-class Bar : public QObject {
+class Bar : public QObject
+{
Q_OBJECT
Q_PROPERTY(FooEnum enum READ enum WRITE setEnum NOTIFY enumChanged)
};
@@ -108,37 +101,46 @@ class Bar : public QObject {
Refer to the type directly:
\code
-class Bar : public QObject {
+class Bar : public QObject
+{
Q_OBJECT
Q_PROPERTY(Foo::Enum enum READ enum WRITE setEnum NOTIFY enumChanged)
};
\endcode
+In order to make \c Message available you need to use \l{QML_ELEMENT} in C++
+and \l{qt_add_qml_module} in CMake.
+
\code
class Message : public QObject
{
Q_OBJECT
+ QML_ELEMENT
Q_PROPERTY(QString author READ author WRITE setAuthor NOTIFY authorChanged)
public:
- void setAuthor(const QString &a) {
+ void setAuthor(const QString &a)
+ {
if (a != m_author) {
m_author = a;
emit authorChanged();
}
}
- QString author() const {
+
+ QString author() const
+ {
return m_author;
}
+
signals:
void authorChanged();
+
private:
QString m_author;
};
\endcode
-If an instance of this class was \l{Embedding C++ Objects into QML with Context
-Properties}{set as a context property} when loading a file named \c MyItem.qml
-from C++:
+An instance of \c Message can be passed as required property to a file called
+\c MyItem.qml to make it available:
\code
int main(int argc, char *argv[]) {
@@ -146,7 +148,7 @@ from C++:
QQuickView view;
Message msg;
- view.engine()->rootContext()->setContextProperty("msg", &msg);
+ view.setInitialProperties({{"msg", &msg}});
view.setSource(QUrl::fromLocalFile("MyItem.qml"));
view.show();
@@ -158,9 +160,11 @@ Then, the \c author property could be read from \c MyItem.qml:
\qml
// MyItem.qml
-import QtQuick 2.0
+import QtQuick
Text {
+ required property Message msg
+
width: 100; height: 100
text: msg.author // invokes Message::author() to get this value
@@ -397,6 +401,8 @@ that is a public slot:
class MessageBoard : public QObject
{
Q_OBJECT
+ QML_ELEMENT
+
public:
Q_INVOKABLE bool postMessage(const QString &msg) {
qDebug() << "Called the C++ method with" << msg;
@@ -410,7 +416,7 @@ that is a public slot:
};
\endcode
-If an instance of \c MessageBoard was set as the context data for a file \c
+If an instance of \c MessageBoard was set as the required property for a file \c
MyItem.qml, then \c MyItem.qml could invoke the two methods as shown in the
examples below:
@@ -424,7 +430,7 @@ examples below:
MessageBoard msgBoard;
QQuickView view;
- view.engine()->rootContext()->setContextProperty("msgBoard", &msgBoard);
+ view.setInitialProperties({{"msgBoard", &msgBoard}});
view.setSource(QUrl::fromLocalFile("MyItem.qml"));
view.show();
@@ -439,6 +445,8 @@ examples below:
import QtQuick 2.0
Item {
+ required property MessageBoard msgBoard
+
width: 100; height: 100
MouseArea {
@@ -464,6 +472,54 @@ be called according to the number and the types of arguments that are provided.
Values returned from C++ methods are converted to JavaScript values when
accessed from JavaScript expressions in QML.
+\section2 C++ methods and the 'this' object
+
+You may want to retrieve a C++ method from one object and call it on a different
+object. Consider the following example, within a QML module called \c{Example}:
+
+\table
+\row
+\li C++
+\li
+\code
+class Invokable : public QObject
+{
+ Q_OBJECT
+ QML_ELEMENT
+public:
+ Invokable(QObject *parent = nullptr) : QObject(parent) {}
+
+ Q_INVOKABLE void invoke() { qDebug() << "invoked on " << objectName(); }
+};
+\endcode
+\row
+\li QML
+\li
+\qml
+import QtQml
+import Example
+
+Invokable {
+ objectName: "parent"
+ property Invokable child: Invokable {}
+ Component.onCompleted: child.invoke.call(this)
+}
+\endqml
+\endtable
+
+If you load the QML code from a suitable main.cpp, it should print
+"invoked on parent". However, due to a long standing bug, it doesn't.
+Historically, the 'this' object of C++-based methods is inseparably bound to
+the method. Changing this behavior for existing code would cause subtle errors
+since the 'this' object is implicit in many places. Since Qt 6.5 you can
+explicitly opt into the correct behavior and allow C++ methods to accept a
+'this' object. To do so, add the following pragma to your QML documents:
+
+\qml
+pragma NativeMethodBehavior: AcceptThisObject
+\endqml
+
+With this line added, the example above will work as expected.
\section1 Exposing Signals