summaryrefslogtreecommitdiff
path: root/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project
diff options
context:
space:
mode:
authorOlivier De Cannière <olivier.decanniere@qt.io>2023-03-17 15:42:47 +0100
committerOlivier De Cannière <olivier.decanniere@qt.io>2023-03-30 18:02:16 +0200
commit405bd4299819e39397cea0090a9442fd4b6ce911 (patch)
treec1254e18a8ab47cc6bde048eb52ad0d89c2492c8 /examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project
parent03ff348b4942ae29dd5bc2bd563998d7ba82ecd7 (diff)
downloadqtdeclarative-405bd4299819e39397cea0090a9442fd4b6ce911.tar.gz
Doc: Revamp "Extending QML" examples into a tutorial
The examples in the "Extending QML" series were often redundant with the information of the "Writing QML Extensions with C++" tutorial, had outdated code and sometimes had no documentation. The examples that covered topics not mentioned in the first tutorial were revamped into a second "advanced" tutorial extending the first one. The others were removed. The remaining examples were largely based on the same example code of a birthday party. This code was slightly adapted and separated into 7 states, each building upon the previous, with the code change illustrating the associated feature. A tutorial page, in the style of the first one, was added documenting the different QML features and the required code changes in the example project. Links in the documentation from and to the affected pages were update as best as possible. Pick-to: 6.5 Fixes: QTBUG-111033 Change-Id: I9d97e8b32b128c1624d67525996fa14d493909d3 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io> Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
Diffstat (limited to 'examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project')
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/CMakeLists.txt43
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/Main.qml16
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/baseproject.pro13
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/baseproject.qrc6
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/birthdayparty.cpp99
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/birthdayparty.h48
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/main.cpp32
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/person.cpp30
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/person.h34
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/qmldir.in4
10 files changed, 325 insertions, 0 deletions
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/CMakeLists.txt b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/CMakeLists.txt
new file mode 100644
index 0000000000..a8064b77ef
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/CMakeLists.txt
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(baseproject LANGUAGES CXX)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/tutorials/extending-qml-advanced/advanced1-Basic-project")
+
+find_package(Qt6 REQUIRED COMPONENTS Core Qml)
+qt_standard_project_setup()
+
+qt_policy(SET QTP0001 NEW)
+
+qt_add_executable(baseproject
+ birthdayparty.cpp birthdayparty.h
+ main.cpp
+ person.cpp person.h
+)
+
+set_target_properties(baseproject PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(baseproject PUBLIC
+ Qt::Core
+ Qt::Qml
+)
+
+qt_add_qml_module(baseproject
+ URI People
+ QML_FILES Main.qml
+)
+
+install(TARGETS baseproject
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/Main.qml b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/Main.qml
new file mode 100644
index 0000000000..c917d5b1f1
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/Main.qml
@@ -0,0 +1,16 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import People
+
+BirthdayParty {
+ host: Person {
+ name: "Bob Jones"
+ shoeSize: 12
+ }
+ guests: [
+ Person { name: "Leo Hodges" },
+ Person { name: "Jack Smith" },
+ Person { name: "Anne Brown" }
+ ]
+}
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/baseproject.pro b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/baseproject.pro
new file mode 100644
index 0000000000..26c865fbba
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/baseproject.pro
@@ -0,0 +1,13 @@
+QT = core qml
+
+CONFIG += qmltypes
+QML_IMPORT_NAME = People
+QML_IMPORT_MAJOR_VERSION = 1
+
+SOURCES += main.cpp \
+ person.cpp \
+ birthdayparty.cpp
+HEADERS += person.h \
+ birthdayparty.h
+
+RESOURCES += baseproject.qrc
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/baseproject.qrc b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/baseproject.qrc
new file mode 100644
index 0000000000..b1eeb489e2
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/baseproject.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource prefix="/qt/qml/People/">
+ <file>Main.qml</file>
+ <file alias="qmldir">qmldir.in</file>
+</qresource>
+</RCC>
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/birthdayparty.cpp b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/birthdayparty.cpp
new file mode 100644
index 0000000000..ad38f284e7
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/birthdayparty.cpp
@@ -0,0 +1,99 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "birthdayparty.h"
+
+Person *BirthdayParty::host() const
+{
+ return m_host;
+}
+
+void BirthdayParty::setHost(Person *host)
+{
+ if (m_host != host) {
+ m_host = host;
+ emit hostChanged();
+ }
+}
+
+QQmlListProperty<Person> BirthdayParty::guests()
+{
+ return { this,
+ this,
+ &BirthdayParty::appendGuest,
+ &BirthdayParty::guestCount,
+ &BirthdayParty::guest,
+ &BirthdayParty::clearGuests,
+ &BirthdayParty::replaceGuest,
+ &BirthdayParty::removeLastGuest };
+}
+
+void BirthdayParty::appendGuest(Person *guest)
+{
+ m_guests.append(guest);
+ emit guestsChanged();
+}
+
+qsizetype BirthdayParty::guestCount() const
+{
+ return m_guests.count();
+}
+
+Person *BirthdayParty::guest(qsizetype index) const
+{
+ return m_guests.at(index);
+}
+
+void BirthdayParty::clearGuests()
+{
+ if (!m_guests.empty()) {
+ m_guests.clear();
+ emit guestsChanged();
+ }
+}
+
+void BirthdayParty::replaceGuest(qsizetype index, Person *guest)
+{
+ if (m_guests.size() > index) {
+ m_guests[index] = guest;
+ emit guestsChanged();
+ }
+}
+
+void BirthdayParty::removeLastGuest()
+{
+ if (!m_guests.empty()) {
+ m_guests.removeLast();
+ emit guestsChanged();
+ }
+}
+
+void BirthdayParty::appendGuest(QQmlListProperty<Person> *list, Person *guest)
+{
+ static_cast<BirthdayParty *>(list->data)->appendGuest(guest);
+}
+
+void BirthdayParty::clearGuests(QQmlListProperty<Person> *list)
+{
+ static_cast<BirthdayParty *>(list->data)->clearGuests();
+}
+
+void BirthdayParty::replaceGuest(QQmlListProperty<Person> *list, qsizetype index, Person *guest)
+{
+ static_cast<BirthdayParty *>(list->data)->replaceGuest(index, guest);
+}
+
+void BirthdayParty::removeLastGuest(QQmlListProperty<Person> *list)
+{
+ static_cast<BirthdayParty *>(list->data)->removeLastGuest();
+}
+
+Person *BirthdayParty::guest(QQmlListProperty<Person> *list, qsizetype index)
+{
+ return static_cast<BirthdayParty *>(list->data)->guest(index);
+}
+
+qsizetype BirthdayParty::guestCount(QQmlListProperty<Person> *list)
+{
+ return static_cast<BirthdayParty *>(list->data)->guestCount();
+}
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/birthdayparty.h b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/birthdayparty.h
new file mode 100644
index 0000000000..1a28ef2632
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/birthdayparty.h
@@ -0,0 +1,48 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef BIRTHDAYPARTY_H
+#define BIRTHDAYPARTY_H
+
+#include "person.h"
+
+#include <QObject>
+#include <QQmlListProperty>
+
+class BirthdayParty : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(Person *host READ host WRITE setHost NOTIFY hostChanged FINAL)
+ Q_PROPERTY(QQmlListProperty<Person> guests READ guests NOTIFY guestsChanged FINAL)
+ QML_ELEMENT
+public:
+ using QObject::QObject;
+
+ Person *host() const;
+ void setHost(Person *);
+
+ QQmlListProperty<Person> guests();
+ void appendGuest(Person *);
+ qsizetype guestCount() const;
+ Person *guest(qsizetype) const;
+ void clearGuests();
+ void replaceGuest(qsizetype, Person *);
+ void removeLastGuest();
+
+signals:
+ void hostChanged();
+ void guestsChanged();
+
+private:
+ static void appendGuest(QQmlListProperty<Person> *, Person *);
+ static qsizetype guestCount(QQmlListProperty<Person> *);
+ static Person *guest(QQmlListProperty<Person> *, qsizetype);
+ static void clearGuests(QQmlListProperty<Person> *);
+ static void replaceGuest(QQmlListProperty<Person> *, qsizetype, Person *);
+ static void removeLastGuest(QQmlListProperty<Person> *);
+
+ Person *m_host = nullptr;
+ QList<Person *> m_guests;
+};
+
+#endif // BIRTHDAYPARTY_H
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/main.cpp b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/main.cpp
new file mode 100644
index 0000000000..eac94016d2
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/main.cpp
@@ -0,0 +1,32 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "birthdayparty.h"
+#include "person.h"
+
+#include <QCoreApplication>
+#include <QDebug>
+#include <QQmlComponent>
+#include <QQmlEngine>
+
+int main(int argc, char **argv)
+{
+ QCoreApplication app(argc, argv);
+
+ QQmlEngine engine;
+ QQmlComponent component(&engine);
+ component.loadFromModule("People", "Main");
+ std::unique_ptr<BirthdayParty> party{ qobject_cast<BirthdayParty *>(component.create()) };
+
+ if (party && party->host()) {
+ qInfo() << party->host()->name()
+ << "is having a birthday!\n"
+ "They are inviting:";
+ for (qsizetype ii = 0; ii < party->guestCount(); ++ii)
+ qInfo() << " " << party->guest(ii)->name();
+ return EXIT_SUCCESS;
+ }
+
+ qWarning() << component.errors();
+ return EXIT_FAILURE;
+}
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/person.cpp b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/person.cpp
new file mode 100644
index 0000000000..f8f4b1d2f4
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/person.cpp
@@ -0,0 +1,30 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "person.h"
+
+QString Person::name() const
+{
+ return m_name;
+}
+
+void Person::setName(const QString &name)
+{
+ if (m_name != name) {
+ m_name = name;
+ emit nameChanged();
+ }
+}
+
+int Person::shoeSize() const
+{
+ return m_shoeSize;
+}
+
+void Person::setShoeSize(int shoeSize)
+{
+ if (m_shoeSize != shoeSize) {
+ m_shoeSize = shoeSize;
+ emit shoeSizeChanged();
+ }
+}
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/person.h b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/person.h
new file mode 100644
index 0000000000..ded272626a
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/person.h
@@ -0,0 +1,34 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef PERSON_H
+#define PERSON_H
+
+#include <QtQml/qqml.h>
+#include <QObject>
+
+class Person : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged FINAL)
+ Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize NOTIFY shoeSizeChanged FINAL)
+ QML_ELEMENT
+public:
+ using QObject::QObject;
+
+ QString name() const;
+ void setName(const QString &);
+
+ int shoeSize() const;
+ void setShoeSize(int);
+
+signals:
+ void nameChanged();
+ void shoeSizeChanged();
+
+private:
+ QString m_name;
+ int m_shoeSize = 0;
+};
+
+#endif // PERSON_H
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/qmldir.in b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/qmldir.in
new file mode 100644
index 0000000000..70cde3c958
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced1-Base-project/qmldir.in
@@ -0,0 +1,4 @@
+module People
+typeinfo birthdayparty.qmltypes
+prefer :/qt/qml/People/
+Main 254.0 Main.qml