aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/doc/src/cppintegration/extending-tutorial.qdoc
diff options
context:
space:
mode:
Diffstat (limited to 'src/qml/doc/src/cppintegration/extending-tutorial.qdoc')
-rw-r--r--src/qml/doc/src/cppintegration/extending-tutorial.qdoc194
1 files changed, 103 insertions, 91 deletions
diff --git a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc
index 6e6d067ba6..156ad47089 100644
--- a/src/qml/doc/src/cppintegration/extending-tutorial.qdoc
+++ b/src/qml/doc/src/cppintegration/extending-tutorial.qdoc
@@ -1,36 +1,12 @@
-/****************************************************************************
-**
-** 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) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
-\example tutorials/extending-qml
+\page qtqml-tutorials-extending-qml-example.html
\title Writing QML Extensions with C++
\brief Tutorial about extending QML with Qt C++.
-The \l {Qt QML} module provides a set of APIs for extending QML through
+The \l {Qt Qml} module provides a set of APIs for extending QML through
C++ extensions. You can write extensions to add your own QML types, extend existing
Qt types, or call C/C++ functions that are not accessible from ordinary QML code.
@@ -39,18 +15,24 @@ core QML features, including properties, signals and bindings. It also shows how
extensions can be deployed through plugins.
Many of the topics covered in this tutorial are documented in further detail in
-\l {qtqml-cppintegration-topic.html}{Integrating QML and C++} and its documentation
-sub-topics. In particular, you may be interested in the sub-topics
+\l{Overview - QML and C++ Integration} and its documentation sub-topics. In
+particular, you may be interested in the sub-topics
\l{qtqml-cppintegration-exposecppattributes.html}{Exposing Attributes of C++ Classes to QML}
and \l {qtqml-cppintegration-definetypes.html}{Defining QML Types from C++}.
-\section1 Running the Tutorial Examples
+\section1 Opening the Tutorial Sources
-The code in this tutorial is available as an example project with subprojects
-associated with each tutorial chapter. In \l{Qt Creator Manual}{Qt Creator}, open
-the \uicontrol Welcome mode and select the tutorial from \uicontrol Examples. In
-\uicontrol Edit mode, expand the \e extending-qml project, right-click on the
-subproject (chapter) you want to run and select \uicontrol Run.
+The code in this tutorial is available as part of the Qt sources.
+If you installed Qt with the \QOI, you can
+find the sources in the Qt installation directory under
+Examples/Qt-\QtVersion/qml/tutorials/extending-qml/.
+
+\section1 Creating Project from Scratch
+
+Alternatively, you can follow the tutorial by creating the sources from scratch:
+For each chapter, create a new project using the \e {Qt Quick Application} template
+in Qt Creator, as instructed in \l {Qt Creator: Creating Qt Quick Projects}.
+Then follow along by adapting and extending the generated skeleton code.
\section1 Chapter 1: Creating a New Type
\c extending-qml/chapter1-basics
@@ -72,15 +54,15 @@ a version of 1.0.
We want this \c PieChart type to be usable from QML like this:
-\badcode
- import Charts 1.0
+\qml
+ import Charts
PieChart {
width: 100; height: 100
name: "A simple pie chart"
color: "red"
}
-\endcode
+\endqml
To do this, we need a C++ class that encapsulates this \c PieChart type and its two
properties. Since QML makes extensive use of Qt's \l{Meta-Object System}{meta object system},
@@ -91,12 +73,14 @@ this new class must:
\li Declare its properties using the Q_PROPERTY macro
\endlist
+\section2 Class Declaration
+
Here is our \c PieChart class, defined in \c piechart.h:
\snippet tutorials/extending-qml/chapter1-basics/piechart.h 0
The class inherits from QQuickPaintedItem because we want to override
-QQuickPaintedItem::paint() in perform drawing operations with the QPainter API.
+QQuickPaintedItem::paint() to perform drawing operations with the QPainter API.
If the class just represented some data type and was not an item that actually needed
to be displayed, it could simply inherit from QObject. Or, if we want to extend the
functionality of an existing QObject-based class, it could inherit from that class instead.
@@ -106,48 +90,68 @@ operations with the QPainter API, we can just subclass QQuickItem.
The \c PieChart class defines the two properties, \c name and \c color, with the
Q_PROPERTY macro, and overrides QQuickPaintedItem::paint(). The \c PieChart
class is registered using the QML_ELEMENT macro, to allow it to be used from
-QML. If you don't register the class, \c app.qml won't be able to create a
+QML. If you don't register the class, \c App.qml won't be able to create a
\c PieChart.
+\section2 qmake Setup
+
For the registration to take effect, the \c qmltypes option is added to
\c CONFIG in the project file and a \c QML_IMPORT_NAME and
\c QML_IMPORT_MAJOR_VERSION are given:
\snippet tutorials/extending-qml/chapter1-basics/chapter1-basics.pro 0
+\section2 CMake Setup
+
+Similarly, for the registration to take effect when using CMake, use the
+\l{qt6_add_qml_module} {qt_add_qml_module} command:
+
+\snippet tutorials/extending-qml/chapter1-basics/CMakeLists.txt 0
+
+\section2 Class Implementation
+
The class implementation in \c piechart.cpp simply sets and returns the
\c m_name and \c m_color values as appropriate, and implements \c paint() to
-draw a simple pie chart. It also turns off the QGraphicsItem::ItemHasNoContents
-flag to enable painting:
+draw a simple pie chart:
\snippet tutorials/extending-qml/chapter1-basics/piechart.cpp 0
\dots 0
\snippet tutorials/extending-qml/chapter1-basics/piechart.cpp 1
-Now that we have defined the \c PieChart type, we will use it from QML. The \c app.qml
-file creates a \c PieChart item and display the pie chart's details
+\section2 QML Usage
+
+Now that we have defined the \c PieChart type, we will use it from QML. The \c
+App.qml file creates a \c PieChart item and displays the pie chart's details
using a standard QML \l Text item:
-\snippet tutorials/extending-qml/chapter1-basics/app.qml 0
+\snippet tutorials/extending-qml/chapter1-basics/App.qml 0
Notice that although the color is specified as a string in QML, it is automatically
converted to a QColor object for the PieChart \c color property. Automatic conversions are
-provided for various other \l {QML Basic Types}{basic types}; for example, a string
+provided for various other \l {QML Value Types}{value types}. For example, a string
like "640x480" can be automatically converted to a QSize value.
We'll also create a C++ application that uses a QQuickView to run and
-display \c app.qml.
+display \c App.qml.
Here is the application \c main.cpp:
\snippet tutorials/extending-qml/chapter1-basics/main.cpp 0
-We write a \c .pro project file that includes the files and the \c qml library, and
-defines a type namespace called "Charts" with a version of 1.0 for any types exposed
-to QML:
+\section2 Project Build
+
+To build the project we include the files, link against the libraries, and
+define a type namespace called "Charts" with version 1.0 for any types exposed
+to QML.
+
+Using qmake:
\quotefile tutorials/extending-qml/chapter1-basics/chapter1-basics.pro
+Using CMake:
+
+\quotefile tutorials/extending-qml/chapter1-basics/CMakeLists.txt
+
Now we can build and run the application:
\image extending-tutorial-chapter1.png
@@ -158,18 +162,14 @@ Now we can build and run the application:
cannot update the binding if the \c name value changes. This is addressed in
the following chapters.
-The source code from the following files are referred to in this chapter:
-\noautolist
-\generatelist examplefiles .*chapter1.*
-
\section1 Chapter 2: Connecting to C++ Methods and Signals
\c extending-qml/chapter2-methods
Suppose we want \c PieChart to have a "clearChart()" method that erases the
-chart and then emits a "chartCleared" signal. Our \c app.qml would be able
+chart and then emits a "chartCleared" signal. Our \c App.qml would be able
to call \c clearChart() and receive \c chartCleared() signals like this:
-\snippet tutorials/extending-qml/chapter2-methods/app.qml 0
+\snippet tutorials/extending-qml/chapter2-methods/App.qml 0
\image extending-tutorial-chapter2.png
@@ -201,8 +201,7 @@ disappears, and the application outputs:
qml: The chart has been cleared
\endcode
-The source code from the following files are referred to in this chapter:
-\generatelist examplefiles .*chapter2.*
+
\section1 Chapter 3: Adding Property Bindings
\c extending-qml/chapter3-bindings
@@ -214,7 +213,7 @@ other types' values when property values are changed.
Let's enable property bindings for the \c color property. That means
if we have code like this:
-\snippet tutorials/extending-qml/chapter3-bindings/app.qml 0
+\snippet tutorials/extending-qml/chapter3-bindings/App.qml 0
\image extending-tutorial-chapter3.png
@@ -237,7 +236,7 @@ is emitted whenever the value changes.
\dots
\snippet tutorials/extending-qml/chapter3-bindings/piechart.h 3
-Then, we emit this signal in \c setPieSlice():
+Then, we emit this signal in \c setColor():
\snippet tutorials/extending-qml/chapter3-bindings/piechart.cpp 0
@@ -252,8 +251,7 @@ automatically updated and cannot be used as flexibly in QML. Also, since
bindings are invoked so often and relied upon in QML usage, users of your
custom QML types may see unexpected behavior if bindings are not implemented.
-The source code from the following files are referred to in this chapter:
-\generatelist examplefiles .*chapter3.*
+
\section1 Chapter 4: Using Custom Property Types
@@ -297,7 +295,7 @@ For example, let's replace the use of the \c property with a type called
"PieSlice" that has a \c color property. Instead of assigning a color,
we assign an \c PieSlice value which itself contains a \c color:
-\snippet tutorials/extending-qml/chapter4-customPropertyTypes/app.qml 0
+\snippet tutorials/extending-qml/chapter4-customPropertyTypes/App.qml 0
Like \c PieChart, this new \c PieSlice type inherits from QQuickPaintedItem and declares
its properties with Q_PROPERTY():
@@ -323,15 +321,26 @@ item when its contents are drawn:
\snippet tutorials/extending-qml/chapter4-customPropertyTypes/piechart.cpp 0
Like the \c PieChart type, the \c PieSlice type has to be exposted to QML
-using QML_ELEMENT. As with \c PieChart, we add the "Charts" type namespace,
-version 1.0 to the .pro file:
+using QML_ELEMENT.
\snippet tutorials/extending-qml/chapter4-customPropertyTypes/pieslice.h 0
\dots
+
+As with \c PieChart, we add the "Charts" type namespace, version 1.0, to our
+build file:
+
+Using qmake:
+
\quotefile tutorials/extending-qml/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pro
-The source code from the following files are referred to in this chapter:
-\generatelist examplefiles .*chapter4.*
+Using CMake:
+
+\dots
+\snippet tutorials/extending-qml/chapter4-customPropertyTypes/CMakeLists.txt 0
+\snippet tutorials/extending-qml/chapter4-customPropertyTypes/CMakeLists.txt 1
+\dots
+
+
\section1 Chapter 5: Using List Property Types
\c extending-qml/chapter5-listproperties
@@ -340,7 +349,7 @@ Right now, a \c PieChart can only have one \c PieSlice. Ideally a chart would
have multiple slices, with different colors and sizes. To do this, we could
have a \c slices property that accepts a list of \c PieSlice items:
-\snippet tutorials/extending-qml/chapter5-listproperties/app.qml 0
+\snippet tutorials/extending-qml/chapter5-listproperties/App.qml 0
\image extending-tutorial-chapter5.png
@@ -375,14 +384,13 @@ The \c PieSlice class has also been modified to include \c fromAngle and \c angl
properties and to draw the slice according to these values. This is a straightforward
modification if you have read the previous pages in this tutorial, so the code is not shown here.
-The source code from the following files are referred to in this chapter:
-\generatelist examplefiles .*chapter5.*
+
\section1 Chapter 6: Writing an Extension Plugin
\c extending-qml/chapter6-plugins
-Currently the \c PieChart and \c PieSlice types are used by \c app.qml,
+Currently the \c PieChart and \c PieSlice types are used by \c App.qml,
which is displayed using a QQuickView in a C++ application. An alternative
way to use our QML extension is to create a plugin library to make it available
to the QML engine as a new QML import module. This allows the \c PieChart and
@@ -397,23 +405,27 @@ plugin with the Qt meta object system.
Here is the \c ChartsPlugin definition in \c chartsplugin.h:
-\snippet tutorials/extending-qml/chapter6-plugins/import/chartsplugin.h 0
+\snippet tutorials/extending-qml/chapter6-plugins/Charts/chartsplugin.h 0
+
+Then, we configure the build file to define the project as a plugin library.
-Then, we write a \c .pro project file that defines the project as a plugin library
-and specifies with DESTDIR that library files should be built into a \c {../Charts}
-directory.
+Using qmake:
-\quotefile tutorials/extending-qml/chapter6-plugins/import/import.pro
+\quotefile tutorials/extending-qml/chapter6-plugins/Charts/Charts.pro
+
+Using CMake:
+
+\quotefile tutorials/extending-qml/chapter6-plugins/Charts/CMakeLists.txt
When building this example on Windows or Linux, the \c Charts directory will be
located at the same level as the application that uses our new import module.
This way, the QML engine will find our module as the default search path for QML
imports includes the directory of the application executable. On \macos, the
-plugin binary is copied to \c Contents/PlugIns in the the application bundle;
-this path is set in \c {chapter6-plugins/app.pro}:
+plugin binary is copied to \c Contents/PlugIns in the the application bundle.
+With qmake, this path is set in \c {chapter6-plugins/app.pro}:
\quotefromfile tutorials/extending-qml/chapter6-plugins/app.pro
-\skipto osx
+\skipto macos
\printuntil }
To account for this, we also need to add this location as a
@@ -432,23 +444,22 @@ to the same location as the plugin binary.
The \c qmldir file declares the module name and the plugin that is made available
by the module:
-\quotefile tutorials/extending-qml/chapter6-plugins/import/qmldir
+\quotefile tutorials/extending-qml/chapter6-plugins/Charts/qmldir
Now we have a QML module that can be imported to any application, provided that the
QML engine knows where to find it. The example contains an executable that loads
-\c app.qml, which uses the \c {import Charts 1.0} statement. Alternatively, you can
-load the QML file using the \l{Prototyping with qmlscene}{qmlscene tool}, setting the
-import path to the current directory so that it finds the \c qmldir file:
+\c App.qml, which uses the \c {import Charts 1.0} statement. Alternatively, you can
+load the QML file using the \l {Prototyping with the QML Runtime Tool}{qml tool},
+setting the import path to the current directory so that it finds the \c qmldir file:
\code
- qmlscene -I . app.qml
+ qml -I . App.qml
\endcode
The module "Charts" will be loaded by the QML engine, and the types provided by that
module will be available for use in any QML document which imports it.
-The source code from the following files are referred to in this chapter:
-\generatelist examplefiles .*chapter6.*
+
\section1 Chapter 7: Summary
@@ -466,9 +477,9 @@ In this tutorial, we've shown the basic steps for creating a QML extension:
\l {Module Definition qmldir Files}{qmldir} file
\endlist
-The \l{Integrating QML and C++} documentation shows
-other useful features that can be added to QML extensions. For example, we
-could use \l{Default Properties}{default properties} to allow
+The \l{Overview - QML and C++ Integration}{QML and C++ Integration overview}
+documentation shows other useful features that can be added to QML extensions.
+For example, we could use \l{Default Properties}{default properties} to allow
slices to be added without using the \c slices property:
\badcode
@@ -487,5 +498,6 @@ Or randomly add and remove slices from time to time using \l{Property Value Sour
}
\endcode
-\sa {Integrating QML and C++}
+\note To continue learning about QML extensions and features follow the
+\l {Writing advanced QML Extensions with C++} tutorial.
*/