aboutsummaryrefslogtreecommitdiffstats
path: root/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source
diff options
context:
space:
mode:
Diffstat (limited to 'examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source')
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/CMakeLists.txt50
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/Main.qml38
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/birthdayparty.cpp137
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/birthdayparty.h82
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/happybirthdaysong.cpp45
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/happybirthdaysong.h39
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/main.cpp49
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/person.cpp96
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/person.h98
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/qmldir.in5
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/valuesource.pro14
-rw-r--r--examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/valuesource.qrc6
12 files changed, 659 insertions, 0 deletions
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/CMakeLists.txt b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/CMakeLists.txt
new file mode 100644
index 0000000000..e6aa49e5cb
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/CMakeLists.txt
@@ -0,0 +1,50 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+cmake_minimum_required(VERSION 3.16)
+project(valuesource LANGUAGES CXX)
+
+find_package(Qt6 REQUIRED COMPONENTS Core Qml Quick)
+qt_standard_project_setup()
+
+qt_policy(SET QTP0001 NEW)
+
+qt_add_executable(valuesource
+ birthdayparty.cpp birthdayparty.h
+ happybirthdaysong.cpp happybirthdaysong.h
+ main.cpp
+ person.cpp person.h
+)
+
+set_target_properties(valuesource PROPERTIES
+ WIN32_EXECUTABLE TRUE
+ MACOSX_BUNDLE TRUE
+)
+
+target_link_libraries(valuesource PUBLIC
+ Qt6::Core
+ Qt6::Qml
+ Qt6::Quick
+)
+
+qt_add_qml_module(valuesource
+ URI People
+ QML_FILES Main.qml
+ DEPENDENCIES
+ QtQuick
+)
+
+install(TARGETS valuesource
+ BUNDLE DESTINATION .
+ RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+ LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+)
+
+qt_generate_deploy_qml_app_script(
+ TARGET valuesource
+ OUTPUT_SCRIPT deploy_script
+ MACOS_BUNDLE_POST_BUILD
+ NO_UNSUPPORTED_PLATFORM_ERROR
+ DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM
+)
+install(SCRIPT ${deploy_script})
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/Main.qml b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/Main.qml
new file mode 100644
index 0000000000..7f79d0a0c4
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/Main.qml
@@ -0,0 +1,38 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import People
+import QtQuick // For QColor
+
+BirthdayParty {
+ id: party
+ HappyBirthdaySong on announcement {
+ name: party.host.name
+ }
+
+ onPartyStarted: (time) => { console.log("This party started rockin' at " + time); }
+
+
+ host: Boy {
+ name: "Bob Jones"
+ shoe { size: 12; color: "white"; brand: "Nike"; price: 90.0 }
+ }
+
+ Boy {
+ name: "Leo Hodges"
+ BirthdayParty.rsvp: Date.fromLocaleString(Qt.locale(), "2023-03-01", "yyyy-MM-dd")
+ shoe { size: 10; color: "black"; brand: "Reebok"; price: 59.95 }
+ }
+ Boy {
+ name: "Jack Smith"
+ shoe { size: 8; color: "blue"; brand: "Puma"; price: 19.95 }
+ }
+ Girl {
+ name: "Anne Brown"
+ BirthdayParty.rsvp: Date.fromLocaleString(Qt.locale(), "2023-03-03", "yyyy-MM-dd")
+ shoe.size: 7
+ shoe.color: "red"
+ shoe.brand: "Marc Jacobs"
+ shoe.price: 99.99
+ }
+}
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/birthdayparty.cpp b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/birthdayparty.cpp
new file mode 100644
index 0000000000..b14f7ef315
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/birthdayparty.cpp
@@ -0,0 +1,137 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "birthdayparty.h"
+
+QDate BirthdayPartyAttached::rsvp() const
+{
+ return m_rsvp;
+}
+
+void BirthdayPartyAttached::setRsvp(QDate rsvpDate)
+{
+ if (m_rsvp != rsvpDate) {
+ m_rsvp = rsvpDate;
+ emit rsvpChanged();
+ }
+}
+
+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();
+}
+
+void BirthdayParty::startParty()
+{
+ QDateTime time = QDateTime::currentDateTime();
+ emit partyStarted(time);
+}
+
+QString BirthdayParty::announcement() const
+{
+ return m_announcement;
+}
+
+void BirthdayParty::setAnnouncement(const QString &announcement)
+{
+ if (m_announcement != announcement) {
+ m_announcement = announcement;
+ emit announcementChanged();
+ }
+ qInfo().noquote() << announcement;
+}
+
+BirthdayPartyAttached *BirthdayParty::qmlAttachedProperties(QObject *object)
+{
+ return new BirthdayPartyAttached(object);
+}
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/birthdayparty.h b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/birthdayparty.h
new file mode 100644
index 0000000000..799a3fa969
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/birthdayparty.h
@@ -0,0 +1,82 @@
+// 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 <QDate>
+#include <QDebug>
+#include <QObject>
+#include <QQmlListProperty>
+#include <qqml.h>
+
+class BirthdayPartyAttached : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QDate rsvp READ rsvp WRITE setRsvp NOTIFY rsvpChanged FINAL)
+ QML_ANONYMOUS
+public:
+ using QObject::QObject;
+
+ QDate rsvp() const;
+ void setRsvp(QDate);
+
+signals:
+ void rsvpChanged();
+
+private:
+ QDate m_rsvp;
+};
+
+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)
+ Q_PROPERTY(QString announcement READ announcement WRITE setAnnouncement NOTIFY announcementChanged FINAL)
+ Q_CLASSINFO("DefaultProperty", "guests")
+ QML_ELEMENT
+ QML_ATTACHED(BirthdayPartyAttached)
+public:
+ using QObject::QObject;
+
+ Person *host() const;
+ void setHost(Person *);
+
+ QString announcement() const;
+ void setAnnouncement(const QString &);
+
+ QQmlListProperty<Person> guests();
+ void appendGuest(Person *);
+ qsizetype guestCount() const;
+ Person *guest(qsizetype) const;
+ void clearGuests();
+ void replaceGuest(qsizetype, Person *);
+ void removeLastGuest();
+
+ static BirthdayPartyAttached *qmlAttachedProperties(QObject *);
+
+ void startParty();
+
+signals:
+ void hostChanged();
+ void guestsChanged();
+ void partyStarted(QDateTime time);
+ void announcementChanged();
+
+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;
+ QString m_announcement;
+};
+
+#endif // BIRTHDAYPARTY_H
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/happybirthdaysong.cpp b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/happybirthdaysong.cpp
new file mode 100644
index 0000000000..7a756a4a71
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/happybirthdaysong.cpp
@@ -0,0 +1,45 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "happybirthdaysong.h"
+
+#include <QTimer>
+
+HappyBirthdaySong::HappyBirthdaySong(QObject *parent) : QObject(parent)
+{
+ auto *timer = new QTimer(this);
+ QObject::connect(timer, &QTimer::timeout, this, &HappyBirthdaySong::advance);
+ timer->start(1000);
+}
+
+void HappyBirthdaySong::setTarget(const QQmlProperty &target)
+{
+ m_target = target;
+}
+
+QString HappyBirthdaySong::name() const
+{
+ return m_name;
+}
+
+void HappyBirthdaySong::setName(const QString &name)
+{
+ if (m_name != name) {
+ m_name = name;
+ emit nameChanged();
+ }
+
+ m_lyrics.clear();
+ m_lyrics << "Happy birthday to you,";
+ m_lyrics << "Happy birthday to you,";
+ m_lyrics << "Happy birthday dear " + m_name + ",";
+ m_lyrics << "Happy birthday to you!";
+ m_lyrics << "";
+}
+
+void HappyBirthdaySong::advance()
+{
+ m_line = (m_line + 1) % m_lyrics.count();
+
+ m_target.write(m_lyrics.at(m_line));
+}
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/happybirthdaysong.h b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/happybirthdaysong.h
new file mode 100644
index 0000000000..13907d5485
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/happybirthdaysong.h
@@ -0,0 +1,39 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#ifndef HAPPYBIRTHDAYSONG_H
+#define HAPPYBIRTHDAYSONG_H
+
+#include <QQmlProperty>
+#include <QQmlPropertyValueSource>
+#include <qqml.h>
+#include <QStringList>
+
+class HappyBirthdaySong : public QObject, public QQmlPropertyValueSource
+{
+ Q_OBJECT
+ Q_INTERFACES(QQmlPropertyValueSource)
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged FINAL)
+ QML_ELEMENT
+public:
+ explicit HappyBirthdaySong(QObject *parent = nullptr);
+
+ void setTarget(const QQmlProperty &) override;
+
+ QString name() const;
+ void setName(const QString &);
+
+signals:
+ void nameChanged();
+
+private slots:
+ void advance();
+
+private:
+ qsizetype m_line = -1;
+ QStringList m_lyrics;
+ QQmlProperty m_target;
+ QString m_name;
+};
+
+#endif // HAPPYBIRTHDAYSONG_H
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/main.cpp b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/main.cpp
new file mode 100644
index 0000000000..6d67b6179e
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/main.cpp
@@ -0,0 +1,49 @@
+// 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!";
+
+ if (qobject_cast<Boy *>(party->host()))
+ qInfo() << "He is inviting:";
+ else
+ qInfo() << "She is inviting:";
+
+ for (qsizetype ii = 0; ii < party->guestCount(); ++ii) {
+ Person *guest = party->guest(ii);
+
+ QDate rsvpDate;
+ QObject *attached = qmlAttachedPropertiesObject<BirthdayParty>(guest, false);
+ if (attached)
+ rsvpDate = attached->property("rsvp").toDate();
+
+ if (rsvpDate.isNull())
+ qInfo() << " " << guest->name() << "RSVP date: Hasn't RSVP'd";
+ else
+ qInfo() << " " << guest->name() << "RSVP date:" << rsvpDate.toString();
+ }
+
+ party->startParty();
+ return QCoreApplication::exec();
+ }
+
+ qWarning() << component.errors();
+ return EXIT_FAILURE;
+}
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/person.cpp b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/person.cpp
new file mode 100644
index 0000000000..53cec6b192
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/person.cpp
@@ -0,0 +1,96 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include "person.h"
+
+Person::Person(QObject *parent) : QObject(parent)
+{
+ m_shoe = new ShoeDescription(this);
+}
+
+int ShoeDescription::size() const
+{
+ return m_size;
+}
+
+void ShoeDescription::setSize(int size)
+{
+ if (m_size != size) {
+ m_size = size;
+ emit shoeChanged();
+ }
+}
+
+QColor ShoeDescription::color() const
+{
+ return m_color;
+}
+
+void ShoeDescription::setColor(const QColor &color)
+{
+ if (m_color != color) {
+ m_color = color;
+ emit shoeChanged();
+ }
+}
+
+QString ShoeDescription::brand() const
+{
+ return m_brand;
+}
+
+void ShoeDescription::setBrand(const QString &brand)
+{
+ if (m_brand != brand) {
+ m_brand = brand;
+ emit shoeChanged();
+ }
+}
+
+qreal ShoeDescription::price() const
+{
+ return m_price;
+}
+
+void ShoeDescription::setPrice(qreal price)
+{
+ if (m_price != price) {
+ m_price = price;
+ emit shoeChanged();
+ }
+}
+
+bool ShoeDescription::operatorEqualsImpl(const ShoeDescription &lhs, const ShoeDescription &rhs)
+{
+ return lhs.m_size == rhs.m_size && lhs.m_color == rhs.m_color && lhs.m_brand == rhs.m_brand
+ && lhs.m_price == rhs.m_price;
+}
+
+QString Person::name() const
+{
+ return m_name;
+}
+
+void Person::setName(const QString &name)
+{
+ if (m_name != name) {
+ m_name = name;
+ emit nameChanged();
+ }
+}
+
+ShoeDescription *Person::shoe() const
+{
+ return m_shoe;
+}
+
+void Person::setShoe(ShoeDescription *shoe)
+{
+ if (!shoe)
+ return;
+
+ if (*m_shoe != *shoe) {
+ m_shoe = shoe;
+ emit shoeChanged();
+ }
+}
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/person.h b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/person.h
new file mode 100644
index 0000000000..4f040e491b
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/person.h
@@ -0,0 +1,98 @@
+// 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 <QColor>
+#include <QObject>
+
+class ShoeDescription : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(int size READ size WRITE setSize NOTIFY shoeChanged FINAL)
+ Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY shoeChanged FINAL)
+ Q_PROPERTY(QString brand READ brand WRITE setBrand NOTIFY shoeChanged FINAL)
+ Q_PROPERTY(qreal price READ price WRITE setPrice NOTIFY shoeChanged FINAL)
+ QML_ANONYMOUS
+public:
+ using QObject::QObject;
+
+ int size() const;
+ void setSize(int);
+
+ QColor color() const;
+ void setColor(const QColor &);
+
+ QString brand() const;
+ void setBrand(const QString &);
+
+ qreal price() const;
+ void setPrice(qreal);
+
+ friend bool operator==(const ShoeDescription &lhs, const ShoeDescription &rhs)
+ {
+ return operatorEqualsImpl(lhs, rhs);
+ }
+ friend bool operator!=(const ShoeDescription &lhs, const ShoeDescription &rhs)
+ {
+ return !operatorEqualsImpl(lhs, rhs);
+ }
+
+signals:
+ void shoeChanged();
+
+private:
+ static bool operatorEqualsImpl(const ShoeDescription &, const ShoeDescription &);
+
+ int m_size = 0;
+ QColor m_color;
+ QString m_brand;
+ qreal m_price = 0;
+};
+
+class Person : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged FINAL)
+ Q_PROPERTY(ShoeDescription *shoe READ shoe WRITE setShoe NOTIFY shoeChanged FINAL)
+ QML_ELEMENT
+ QML_UNCREATABLE("Person is an abstract base class.")
+public:
+ using QObject::QObject;
+
+ Person(QObject *parent = nullptr);
+
+ QString name() const;
+ void setName(const QString &);
+
+ ShoeDescription *shoe() const;
+ void setShoe(ShoeDescription *shoe);
+
+signals:
+ void nameChanged();
+ void shoeChanged();
+
+private:
+ QString m_name;
+ ShoeDescription *m_shoe = nullptr;
+};
+
+class Boy : public Person
+{
+ Q_OBJECT
+ QML_ELEMENT
+public:
+ using Person::Person;
+};
+
+class Girl : public Person
+{
+ Q_OBJECT
+ QML_ELEMENT
+public:
+ using Person::Person;
+};
+
+#endif // PERSON_H
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/qmldir.in b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/qmldir.in
new file mode 100644
index 0000000000..4c63c729d6
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/qmldir.in
@@ -0,0 +1,5 @@
+module People
+typeinfo valuesource.qmltypes
+prefer :/qt/qml/People/
+Main 254.0 Main.qml
+depends QtQuick
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/valuesource.pro b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/valuesource.pro
new file mode 100644
index 0000000000..c55299cecf
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/valuesource.pro
@@ -0,0 +1,14 @@
+QT += qml quick
+
+CONFIG += qmltypes
+QML_IMPORT_NAME = People
+QML_IMPORT_MAJOR_VERSION = 1
+
+SOURCES += main.cpp \
+ person.cpp \
+ birthdayparty.cpp \
+ happybirthdaysong.cpp
+HEADERS += person.h \
+ birthdayparty.h \
+ happybirthdaysong.h
+RESOURCES += valuesource.qrc
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/valuesource.qrc b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/valuesource.qrc
new file mode 100644
index 0000000000..b1eeb489e2
--- /dev/null
+++ b/examples/qml/tutorials/extending-qml-advanced/advanced6-Property-value-source/valuesource.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>