diff options
Diffstat (limited to 'examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties')
10 files changed, 346 insertions, 0 deletions
diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/CMakeLists.txt b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/CMakeLists.txt new file mode 100644 index 0000000000..079d965280 --- /dev/null +++ b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/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(default LANGUAGES CXX) + +if(NOT DEFINED INSTALL_EXAMPLESDIR) + set(INSTALL_EXAMPLESDIR "examples") +endif() + +set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/tutorials/extending-qml-advanced/advanced3-Default-properties") + +find_package(Qt6 REQUIRED COMPONENTS Core Qml) +qt_standard_project_setup() + +qt_policy(SET QTP0001 NEW) + +qt_add_executable(default + birthdayparty.cpp birthdayparty.h + main.cpp + person.cpp person.h +) + +set_target_properties(default PROPERTIES + WIN32_EXECUTABLE TRUE + MACOSX_BUNDLE TRUE +) + +target_link_libraries(default PUBLIC + Qt::Core + Qt::Qml +) + +qt_add_qml_module(default + URI People + QML_FILES Main.qml +) + +install(TARGETS default + RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}" + BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}" + LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}" +) diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/Main.qml b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/Main.qml new file mode 100644 index 0000000000..1070427cb0 --- /dev/null +++ b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/Main.qml @@ -0,0 +1,15 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import People + +BirthdayParty { + host: Boy { + name: "Bob Jones" + shoeSize: 12 + } + + Boy { name: "Leo Hodges" } + Boy { name: "Jack Smith" } + Girl { name: "Anne Brown" } +} diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/birthdayparty.cpp b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/birthdayparty.cpp new file mode 100644 index 0000000000..ad38f284e7 --- /dev/null +++ b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/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/advanced3-Default-properties/birthdayparty.h b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/birthdayparty.h new file mode 100644 index 0000000000..4d7e61a487 --- /dev/null +++ b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/birthdayparty.h @@ -0,0 +1,49 @@ +// 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) + Q_CLASSINFO("DefaultProperty", "guests") + 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> *list, 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/advanced3-Default-properties/default.pro b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/default.pro new file mode 100644 index 0000000000..65dd27213b --- /dev/null +++ b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/default.pro @@ -0,0 +1,12 @@ +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 += default.qrc diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/default.qrc b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/default.qrc new file mode 100644 index 0000000000..b1eeb489e2 --- /dev/null +++ b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/default.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/advanced3-Default-properties/main.cpp b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/main.cpp new file mode 100644 index 0000000000..fa26448f44 --- /dev/null +++ b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/main.cpp @@ -0,0 +1,37 @@ +// 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) + qInfo() << " " << party->guest(ii)->name(); + + return EXIT_SUCCESS; + } + + qWarning() << component.errors(); + return EXIT_FAILURE; +} diff --git a/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/person.cpp b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/person.cpp new file mode 100644 index 0000000000..f8f4b1d2f4 --- /dev/null +++ b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/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/advanced3-Default-properties/person.h b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/person.h new file mode 100644 index 0000000000..99fc9209ab --- /dev/null +++ b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/person.h @@ -0,0 +1,51 @@ +// 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 + QML_UNCREATABLE("Person is an abstract base class.") +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; +}; + +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/advanced3-Default-properties/qmldir.in b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/qmldir.in new file mode 100644 index 0000000000..da1b995d64 --- /dev/null +++ b/examples/qml/tutorials/extending-qml-advanced/advanced3-Default-properties/qmldir.in @@ -0,0 +1,4 @@ +module People +typeinfo default.qmltypes +prefer :/qt/qml/People/ +Main 254.0 Main.qml |