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.

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>
(cherry picked from commit 405bd42998)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Olivier De Cannière 2023-03-17 15:42:47 +01:00 committed by Qt Cherry-pick Bot
parent fa4e37e122
commit d740e2753e
158 changed files with 2564 additions and 2735 deletions

View File

@ -6,8 +6,8 @@ designers to actually implement their UI vision. QML UIs can integrate
with C++ code in many ways, including being loaded as a part of a C++ UI
and loading data models from C++ and interacting with them.
Mostof these examples can be viewed directly with the
Most of these examples can be viewed directly with the
QML viewer utility, without requiring compilation.
Documentation for these examples can be found via the Examples
Documentation for these examples can be found via the Examples and Tutorials
link in the main Qt documentation.

View File

@ -1,7 +1,6 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
add_subdirectory(referenceexamples)
add_subdirectory(tutorials)
if(TARGET Qt::Quick)
qt_internal_add_example(qmlextensionplugins)

View File

@ -1,339 +0,0 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
/*!
\example referenceexamples/adding
\title Extending QML - Adding Types Example
\brief Exporting C++ Classes.
\ingroup qmlextendingexamples
The Adding Types Example shows how to add a new object type, \c Person, to QML.
The \c Person type can be used from QML like this:
\snippet referenceexamples/adding/example.qml 0
\section1 Declare the Person Class
All QML types map to C++ types. Here we declare a basic C++ Person class
with the two properties we want accessible on the QML type - name and shoeSize.
Although in this example we use the same name for the C++ class as the QML
type, the C++ class can be named differently, or appear in a namespace.
\snippet referenceexamples/adding/person.h 0
\section1 Define the Person Class
\snippet referenceexamples/adding/person.cpp 0
The Person class implementation is quite basic. The property accessors simply
return members of the object instance.
\section1 Running the Example
The main.cpp file in the example includes a simple shell application that
loads and runs the QML snippet shown at the beginning of this page.
*/
/*!
\example referenceexamples/extended
\title Extending QML - Extension Objects Example
\brief Extension Objects.
\ingroup qmlextendingexamples
This example builds on:
\list
\li \l {Extending QML - Adding Types Example}
\endlist
Shows how to use \l {QML_EXTENDED} to provide an
\l {Registering Extension Objects}{extension object} to a \l QLineEdit without modifying or
subclassing it.
Firstly, the LineEditExtension class is registered with the QML system as an
extension of QLineEdit. We declare a foreign type to do this as we cannot modify
Qt's internal QLineEdit class.
\snippet referenceexamples/extended/lineedit.h 0
Note the usage of \l QML_NAMED_ELEMENT() instead of \l QML_ELEMENT.
QML_ELEMENT uses the name of the containing type by default, "LineEditExtension" in this case.
As the class being an extension class is an implementation detail, we choose the more natural name "LineEdit" instead
The QML engine then instantiates a \l QLineEdit:
\snippet referenceexamples/extended/main.cpp 1
In QML, a property is set on the line edit that only exists in the LineEditExtension class:
\snippet referenceexamples/extended/example.qml 0
The extension type performs calls on the \l QLineEdit that otherwise will
not be accessible to the QML engine.
*/
/*!
\example referenceexamples/properties
\title Extending QML - Object and List Property Types Example
\brief Exporting C++ Properties.
\ingroup qmlextendingexamples
This example builds on:
\list
\li \l {Extending QML - Adding Types Example}
\endlist
The Object and List Property Types example shows how to add object and list
properties in QML. This example adds a BirthdayParty type that specifies
a birthday party, consisting of a celebrant and a list of guests. People are
specified using the People QML type built in the previous example.
\snippet referenceexamples/properties/example.qml 0
\section1 Declare the BirthdayParty
The BirthdayParty class is declared like this:
\snippet referenceexamples/properties/birthdayparty.h 0
\snippet referenceexamples/properties/birthdayparty.h 1
\snippet referenceexamples/properties/birthdayparty.h 2
\snippet referenceexamples/properties/birthdayparty.h 3
The class contains a member to store the celebrant object, and also a
QList<Person *> member.
In QML, the type of a list properties - and the guests property is a list of
people - are all of type QQmlListProperty<T>. QQmlListProperty is simple value
type that contains a set of function pointers. QML calls these function
pointers whenever it needs to read from, write to or otherwise interact with
the list. In addition to concrete lists like the people list used in this
example, the use of QQmlListProperty allows for "virtual lists" and other advanced
scenarios.
\section2 Define the BirthdayParty
The implementation of BirthdayParty property accessors is straight forward.
\snippet referenceexamples/properties/birthdayparty.cpp 0
\section1 Running the Example
The main.cpp file in the example includes a simple shell application that
loads and runs the QML snippet shown at the beginning of this page.
*/
/*!
\example referenceexamples/coercion
\title Extending QML - Inheritance and Coercion Example
\brief C++ Inheritance and Coercion.
\ingroup qmlextendingexamples
This example builds on:
\list
\li \l {Extending QML - Object and List Property Types Example}
\li \l {Extending QML - Adding Types Example}
\endlist
The Inheritance and Coercion Example shows how to use base classes to assign
types of more than one type to a property. It specializes the Person type
developed in the previous examples into two types - a \c Boy and a \c Girl.
\snippet referenceexamples/coercion/example.qml 0
\section1 Declare Boy and Girl
\snippet referenceexamples/coercion/person.h 1
The Person class remains unaltered in this example and the Boy and Girl C++
classes are trivial extensions of it. The types and their QML name are
registered with the QML engine.
As an example, the inheritance used here is a little contrived, but in real
applications it is likely that the two extensions would add additional
properties or modify the Person classes behavior.
\section2 Define People as a Base Class
The implementation of the People class itself has not changed since the
previous example. However, as we have repurposed the People class as a common
base for Boy and Girl, we want to prevent it from being instantiated from QML
directly - an explicit Boy or Girl should be instantiated instead.
\snippet referenceexamples/coercion/person.h 0
While we want to disallow instantiating Person from within QML, it still needs
to be registered with the QML engine, so that it can be used as a property type
and other types can be coerced to it. This is what the QML_UNCREATABLE macro
does.
\section1 Running the Example
The BirthdayParty type has not changed since the previous example. The
celebrant and guests property still use the People type.
\snippet referenceexamples/coercion/birthdayparty.h 0
However, as all three types, Person, Boy and Girl, have been registered with the
QML system, on assignment QML automatically (and type-safely) converts the Boy
and Girl objects into a Person.
The main.cpp file in the example includes a simple shell application that
loads and runs the QML snippet shown at the beginning of this page.
*/
/*!
\example referenceexamples/default
\title Extending QML - Default Property Example
\brief Default Property.
\ingroup qmlextendingexamples
This example builds on:
\list
\li \l {Extending QML - Inheritance and Coercion Example}
\li \l {Extending QML - Object and List Property Types Example}
\li \l {Extending QML - Adding Types Example}
\endlist
The Default Property Example is a minor modification of the
\l {Extending QML - Inheritance and Coercion Example} that simplifies the
specification of a BirthdayParty through the use of a default property.
\snippet referenceexamples/default/example.qml 0
\section1 Declaring the BirthdayParty Class
The only difference between this example and the last, is the addition of the
\c DefaultProperty class info annotation.
\snippet referenceexamples/default/birthdayparty.h 0
The default property specifies the property to assign to whenever an explicit
property is not specified, in the case of the BirthdayParty type the guest
property. It is purely a syntactic simplification, the behavior is identical
to specifying the property by name, but it can add a more natural feel in many
situations. The default property must be either an object or list property.
\section1 Running the Example
The main.cpp file in the example includes a simple shell application that
loads and runs the QML snippet shown at the beginning of this page.
*/
/*!
\example referenceexamples/grouped
\title Extending QML - Grouped Properties Example
\brief Grouped Properties.
\ingroup qmlextendingexamples
This example builds on:
\list
\li \l {Extending QML - Default Property Example}
\li \l {Extending QML - Inheritance and Coercion Example}
\li \l {Extending QML - Object and List Property Types Example}
\li \l {Extending QML - Adding Types Example}
\endlist
*/
/*!
\example referenceexamples/attached
\title Extending QML - Attached Properties Example
\brief Attached Properties.
\ingroup qmlextendingexamples
This example demonstrates how to create custom
\l {Attached Properties and Attached Signal Handlers} {attached properties}.
For a more in-depth description on how one can create attached properties,
see \l {Providing Attached Properties}.
This example builds on:
\list
\li \l {Extending QML - Grouped Properties Example}
\li \l {Extending QML - Default Property Example}
\li \l {Extending QML - Inheritance and Coercion Example}
\li \l {Extending QML - Object and List Property Types Example}
\li \l {Extending QML - Adding Types Example}
\endlist
*/
/*!
\example referenceexamples/signal
\title Extending QML - Signal Support Example
\brief Signal Support.
\ingroup qmlextendingexamples
This example builds on:
\list
\li \l {Extending QML - Attached Properties Example}
\li \l {Extending QML - Grouped Properties Example}
\li \l {Extending QML - Default Property Example}
\li \l {Extending QML - Inheritance and Coercion Example}
\li \l {Extending QML - Object and List Property Types Example}
\li \l {Extending QML - Adding Types Example}
\endlist
*/
/*!
\example referenceexamples/methods
\title Extending QML - Methods Example
\brief Methods Support.
\ingroup qmlextendingexamples
This example builds on:
\list
\li \l {Extending QML - Inheritance and Coercion Example}
\li \l {Extending QML - Object and List Property Types Example}
\li \l {Extending QML - Adding Types Example}
\endlist
The Methods Example has an additional method in the \c BirthdayParty class: \c invite().
\c invite() is declared with \l Q_INVOKABLE so that it can be
called from QML.
\snippet referenceexamples/methods/birthdayparty.h 0
In \c example.qml, the \c invite() method is called in the \l [QML]{QtQml::Component::completed()}{Component.onCompleted} signal handler:
\snippet referenceexamples/methods/example.qml 0
*/
/*!
\example referenceexamples/valuesource
\title Extending QML - Property Value Source Example
\brief Property Value Source.
\ingroup qmlextendingexamples
This example builds on:
\list
\li \l {Extending QML - Signal Support Example}
\li \l {Extending QML - Attached Properties Example}
\li \l {Extending QML - Grouped Properties Example}
\li \l {Extending QML - Default Property Example}
\li \l {Extending QML - Inheritance and Coercion Example}
\li \l {Extending QML - Object and List Property Types Example}
\li \l {Extending QML - Adding Types Example}
\endlist
*/
/*!
\example referenceexamples/binding
\title Extending QML - Binding Example
\brief Binding.
\ingroup qmlextendingexamples
This example builds on:
\list
\li \l {Extending QML - Property Value Source Example}
\li \l {Extending QML - Signal Support Example}
\li \l {Extending QML - Attached Properties Example}
\li \l {Extending QML - Grouped Properties Example}
\li \l {Extending QML - Default Property Example}
\li \l {Extending QML - Inheritance and Coercion Example}
\li \l {Extending QML - Object and List Property Types Example}
\li \l {Extending QML - Adding Types Example}
\endlist
*/

View File

@ -7,7 +7,6 @@ qtHaveModule(quick) {
}
SUBDIRS += \
referenceexamples \
tutorials
EXAMPLE_FILES = \

View File

@ -1,18 +0,0 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
qt_internal_add_example(adding)
qt_internal_add_example(coercion)
qt_internal_add_example(default)
qt_internal_add_example(properties)
qt_internal_add_example(methods)
if(TARGET Qt::Widgets)
qt_internal_add_example(extended)
endif()
if(TARGET Qt::Quick)
qt_internal_add_example(attached)
qt_internal_add_example(binding)
qt_internal_add_example(grouped)
qt_internal_add_example(signal)
qt_internal_add_example(valuesource)
endif()

View File

@ -1,42 +0,0 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(adding LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/referenceexamples/adding")
find_package(Qt6 REQUIRED COMPONENTS Core Qml)
qt_add_executable(adding
main.cpp
person.cpp person.h
)
set_target_properties(adding PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(adding PUBLIC
Qt::Core
Qt::Qml
)
qt_add_qml_module(adding
URI People
QML_FILES example.qml
NO_RESOURCE_TARGET_PATH
)
install(TARGETS adding
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -1,13 +0,0 @@
QT = core qml
CONFIG += qmltypes
QML_IMPORT_NAME = People
QML_IMPORT_MAJOR_VERSION = 1
SOURCES += main.cpp \
person.cpp
HEADERS += person.h
RESOURCES += adding.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/qml/referenceexamples/adding
INSTALLS += target

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>example.qml</file>
</qresource>
</RCC>

View File

@ -1,11 +0,0 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
// ![0]
import People
Person {
name: "Bob Jones"
shoeSize: 12
}
// ![0]

View File

@ -1,26 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QCoreApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QDebug>
#include "person.h"
int main(int argc, char ** argv)
{
QCoreApplication app(argc, argv);
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
auto *person = qobject_cast<Person *>(component.create());
if (!person) {
qWarning() << component.errors();
return EXIT_FAILURE;
}
qInfo() << "The person's name is" << person->name()
<< "\nThey wear a" << person->shoeSize() << "sized shoe";
return EXIT_SUCCESS;
}

View File

@ -1,27 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "person.h"
// ![0]
QString Person::name() const
{
return m_name;
}
void Person::setName(const QString &n)
{
m_name = n;
}
int Person::shoeSize() const
{
return m_shoeSize;
}
void Person::setShoeSize(int s)
{
m_shoeSize = s;
}
// ![0]

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>example.qml</file>
</qresource>
</RCC>

View File

@ -1,45 +0,0 @@
// Copyright (C) 2021 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 d)
{
m_rsvp = d;
}
Person *BirthdayParty::host() const
{
return m_host;
}
void BirthdayParty::setHost(Person *c)
{
m_host = c;
}
QQmlListProperty<Person> BirthdayParty::guests()
{
return {this, &m_guests};
}
qsizetype BirthdayParty::guestCount() const
{
return m_guests.count();
}
Person *BirthdayParty::guest(qsizetype index) const
{
return m_guests.at(index);
}
BirthdayPartyAttached *BirthdayParty::qmlAttachedProperties(QObject *object)
{
return new BirthdayPartyAttached(object);
}

View File

@ -1,57 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef BIRTHDAYPARTY_H
#define BIRTHDAYPARTY_H
#include <QObject>
#include <QDate>
#include <qqml.h>
#include "person.h"
class BirthdayPartyAttached : public QObject
{
Q_OBJECT
Q_PROPERTY(QDate rsvp READ rsvp WRITE setRsvp)
QML_ANONYMOUS
public:
using QObject::QObject;
QDate rsvp() const;
void setRsvp(QDate);
private:
QDate m_rsvp;
};
class BirthdayParty : public QObject
{
Q_OBJECT
Q_PROPERTY(Person *host READ host WRITE setHost)
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
Q_CLASSINFO("DefaultProperty", "guests")
QML_ELEMENT
//! [declare attached]
QML_ATTACHED(BirthdayPartyAttached)
//! [declare attached]
public:
using QObject::QObject;
Person *host() const;
void setHost(Person *);
QQmlListProperty<Person> guests();
qsizetype guestCount() const;
Person *guest(qsizetype) const;
//! [static attached]
static BirthdayPartyAttached *qmlAttachedProperties(QObject *);
//! [static attached]
private:
Person *m_host = nullptr;
QList<Person *> m_guests;
};
#endif // BIRTHDAYPARTY_H

View File

@ -1,59 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "person.h"
int ShoeDescription::size() const
{
return m_size;
}
void ShoeDescription::setSize(int s)
{
m_size = s;
}
QColor ShoeDescription::color() const
{
return m_color;
}
void ShoeDescription::setColor(const QColor &c)
{
m_color = c;
}
QString ShoeDescription::brand() const
{
return m_brand;
}
void ShoeDescription::setBrand(const QString &b)
{
m_brand = b;
}
qreal ShoeDescription::price() const
{
return m_price;
}
void ShoeDescription::setPrice(qreal p)
{
m_price = p;
}
QString Person::name() const
{
return m_name;
}
void Person::setName(const QString &n)
{
m_name = n;
}
ShoeDescription *Person::shoe()
{
return &m_shoe;
}

View File

@ -1,45 +0,0 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(binding LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/referenceexamples/binding")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml)
qt_add_executable(binding
birthdayparty.cpp birthdayparty.h
happybirthdaysong.cpp happybirthdaysong.h
main.cpp
person.cpp person.h
)
set_target_properties(binding PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(binding PUBLIC
Qt::Core
Qt::Gui
Qt::Qml
)
qt_add_qml_module(binding
URI People
QML_FILES example.qml
NO_RESOURCE_TARGET_PATH
)
install(TARGETS binding
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -1,17 +0,0 @@
QT += qml
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 += binding.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/qml/referenceexamples/binding
INSTALLS += target

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>example.qml</file>
</qresource>
</RCC>

View File

@ -1,66 +0,0 @@
// Copyright (C) 2021 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 d)
{
if (d != m_rsvp) {
m_rsvp = d;
emit rsvpChanged();
}
}
Person *BirthdayParty::host() const
{
return m_host;
}
void BirthdayParty::setHost(Person *c)
{
if (c == m_host) return;
m_host = c;
emit hostChanged();
}
QQmlListProperty<Person> BirthdayParty::guests()
{
return QQmlListProperty<Person>(this, &m_guests);
}
qsizetype BirthdayParty::guestCount() const
{
return m_guests.count();
}
Person *BirthdayParty::guest(qsizetype index) const
{
return m_guests.at(index);
}
void BirthdayParty::startParty()
{
QTime time = QTime::currentTime();
emit partyStarted(time);
}
QString BirthdayParty::announcement() const
{
return QString();
}
void BirthdayParty::setAnnouncement(const QString &speak)
{
qWarning().noquote() << speak;
}
BirthdayPartyAttached *BirthdayParty::qmlAttachedProperties(QObject *object)
{
return new BirthdayPartyAttached(object);
}

View File

@ -1,79 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "person.h"
int ShoeDescription::size() const
{
return m_size;
}
void ShoeDescription::setSize(int s)
{
if (m_size == s)
return;
m_size = s;
emit shoeChanged();
}
QColor ShoeDescription::color() const
{
return m_color;
}
void ShoeDescription::setColor(const QColor &c)
{
if (m_color == c)
return;
m_color = c;
emit shoeChanged();
}
QString ShoeDescription::brand() const
{
return m_brand;
}
void ShoeDescription::setBrand(const QString &b)
{
if (m_brand == b)
return;
m_brand = b;
emit shoeChanged();
}
qreal ShoeDescription::price() const
{
return m_price;
}
void ShoeDescription::setPrice(qreal p)
{
if (m_price == p)
return;
m_price = p;
emit shoeChanged();
}
QString Person::name() const
{
return m_name;
}
void Person::setName(const QString &n)
{
if (m_name == n)
return;
m_name = n;
emit nameChanged();
}
ShoeDescription *Person::shoe()
{
return &m_shoe;
}

View File

@ -1,29 +0,0 @@
// Copyright (C) 2021 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 *c)
{
m_host = c;
}
QQmlListProperty<Person> BirthdayParty::guests()
{
return {this, &m_guests};
}
qsizetype BirthdayParty::guestCount() const
{
return m_guests.count();
}
Person *BirthdayParty::guest(qsizetype index) const
{
return m_guests.at(index);
}

View File

@ -1,34 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef BIRTHDAYPARTY_H
#define BIRTHDAYPARTY_H
#include <QObject>
#include <QQmlListProperty>
#include "person.h"
class BirthdayParty : public QObject
{
Q_OBJECT
// ![0]
Q_PROPERTY(Person *host READ host WRITE setHost)
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
QML_ELEMENT
// ![0]
public:
using QObject::QObject;
Person *host() const;
void setHost(Person *);
QQmlListProperty<Person> guests();
qsizetype guestCount() const;
Person *guest(qsizetype) const;
private:
Person *m_host = nullptr;
QList<Person *> m_guests;
};
#endif // BIRTHDAYPARTY_H

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>example.qml</file>
</qresource>
</RCC>

View File

@ -1,24 +0,0 @@
// Copyright (C) 2021 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 &n)
{
m_name = n;
}
int Person::shoeSize() const
{
return m_shoeSize;
}
void Person::setShoeSize(int s)
{
m_shoeSize = s;
}

View File

@ -1,30 +0,0 @@
// Copyright (C) 2021 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 *c)
{
m_host = c;
}
QQmlListProperty<Person> BirthdayParty::guests()
{
return {this, &m_guests};
}
qsizetype BirthdayParty::guestCount() const
{
return m_guests.count();
}
Person *BirthdayParty::guest(qsizetype index) const
{
return m_guests.at(index);
}

View File

@ -1,35 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef BIRTHDAYPARTY_H
#define BIRTHDAYPARTY_H
#include <QObject>
#include <QQmlListProperty>
#include "person.h"
// ![0]
class BirthdayParty : public QObject
{
Q_OBJECT
Q_PROPERTY(Person *host READ host WRITE setHost)
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
Q_CLASSINFO("DefaultProperty", "guests")
QML_ELEMENT
public:
using QObject::QObject;
Person *host() const;
void setHost(Person *);
QQmlListProperty<Person> guests();
qsizetype guestCount() const;
Person *guest(qsizetype) const;
private:
Person *m_host = nullptr;
QList<Person *> m_guests;
};
// ![0]
#endif // BIRTHDAYPARTY_H

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>example.qml</file>
</qresource>
</RCC>

View File

@ -1,24 +0,0 @@
// Copyright (C) 2021 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 &n)
{
m_name = n;
}
int Person::shoeSize() const
{
return m_shoeSize;
}
void Person::setShoeSize(int s)
{
m_shoeSize = s;
}

View File

@ -1,44 +0,0 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(extended LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/referenceexamples/extended")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml Widgets)
qt_add_executable(extended
lineedit.cpp lineedit.h
main.cpp
)
set_target_properties(extended PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(extended PUBLIC
Qt::Core
Qt::Gui
Qt::Qml
Qt::Widgets
)
qt_add_qml_module(extended
URI People
QML_FILES example.qml
NO_RESOURCE_TARGET_PATH
)
install(TARGETS extended
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -1,10 +0,0 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import People
// ![0]
QLineEdit {
leftMargin: 20
}
// ![0]

View File

@ -1,13 +0,0 @@
QT += qml widgets
CONFIG += qmltypes
QML_IMPORT_NAME = People
QML_IMPORT_MAJOR_VERSION = 1
SOURCES += main.cpp \
lineedit.cpp
HEADERS += lineedit.h
RESOURCES += extended.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/qml/referenceexamples/extended
INSTALLS += target

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>example.qml</file>
</qresource>
</RCC>

View File

@ -1,71 +0,0 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "lineedit.h"
#include <qqml.h>
LineEditExtension::LineEditExtension(QObject *object)
: QObject(object), m_lineedit(qobject_cast<QLineEdit *>(object))
{
}
int LineEditExtension::leftMargin() const
{
return m_lineedit->textMargins().left();
}
void LineEditExtension::setLeftMargin(int l)
{
QMargins m = m_lineedit->textMargins();
if (m.left() != l) {
m.setLeft(l);
m_lineedit->setTextMargins(m);
emit marginsChanged();
}
}
int LineEditExtension::rightMargin() const
{
return m_lineedit->textMargins().right();
}
void LineEditExtension::setRightMargin(int r)
{
QMargins m = m_lineedit->textMargins();
if (m.right() != r) {
m.setRight(r);
m_lineedit->setTextMargins(m);
emit marginsChanged();
}
}
int LineEditExtension::topMargin() const
{
return m_lineedit->textMargins().top();
}
void LineEditExtension::setTopMargin(int t)
{
QMargins m = m_lineedit->textMargins();
if (m.top() != t) {
m.setTop(t);
m_lineedit->setTextMargins(m);
emit marginsChanged();
}
}
int LineEditExtension::bottomMargin() const
{
return m_lineedit->textMargins().bottom();
}
void LineEditExtension::setBottomMargin(int b)
{
QMargins m = m_lineedit->textMargins();
if (m.bottom() != b) {
m.setBottom(b);
m_lineedit->setTextMargins(m);
emit marginsChanged();
}
}

View File

@ -1,47 +0,0 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef LINEEDIT_H
#define LINEEDIT_H
#include <QLineEdit>
#include <qqml.h>
class LineEditExtension : public QObject
{
Q_OBJECT
Q_PROPERTY(int leftMargin READ leftMargin WRITE setLeftMargin NOTIFY marginsChanged)
Q_PROPERTY(int rightMargin READ rightMargin WRITE setRightMargin NOTIFY marginsChanged)
Q_PROPERTY(int topMargin READ topMargin WRITE setTopMargin NOTIFY marginsChanged)
Q_PROPERTY(int bottomMargin READ bottomMargin WRITE setBottomMargin NOTIFY marginsChanged)
public:
LineEditExtension(QObject *);
int leftMargin() const;
void setLeftMargin(int);
int rightMargin() const;
void setRightMargin(int);
int topMargin() const;
void setTopMargin(int);
int bottomMargin() const;
void setBottomMargin(int);
signals:
void marginsChanged();
private:
QLineEdit *m_lineedit;
};
// ![0]
struct QLineEditForeign
{
Q_GADGET
QML_FOREIGN(QLineEdit)
QML_NAMED_ELEMENT(QLineEdit)
QML_EXTENDED(LineEditExtension)
};
// ![0]
#endif // LINEEDIT_H

View File

@ -1,27 +0,0 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QDebug>
#include <QLineEdit>
#include "lineedit.h"
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
// ![1]
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
auto *edit = qobject_cast<QLineEdit *>(component.create());
// ![1]
if (edit) {
edit->show();
return QApplication::exec();
}
qWarning() << component.errors();
return EXIT_FAILURE;
}

View File

@ -1,29 +0,0 @@
// Copyright (C) 2021 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 *c)
{
m_host = c;
}
QQmlListProperty<Person> BirthdayParty::guests()
{
return {this, &m_guests};
}
qsizetype BirthdayParty::guestCount() const
{
return m_guests.count();
}
Person *BirthdayParty::guest(qsizetype index) const
{
return m_guests.at(index);
}

View File

@ -1,34 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef BIRTHDAYPARTY_H
#define BIRTHDAYPARTY_H
#include <QObject>
#include <QQmlListProperty>
#include "person.h"
class BirthdayParty : public QObject
{
Q_OBJECT
Q_PROPERTY(Person *host READ host WRITE setHost)
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
Q_CLASSINFO("DefaultProperty", "guests")
QML_ELEMENT
public:
using QObject::QObject;
Person *host() const;
void setHost(Person *);
QQmlListProperty<Person> guests();
qsizetype guestCount() const;
Person *guest(qsizetype) const;
private:
Person *m_host;
QList<Person *> m_guests;
};
#endif // BIRTHDAYPARTY_H

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>example.qml</file>
</qresource>
</RCC>

View File

@ -1,59 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "person.h"
int ShoeDescription::size() const
{
return m_size;
}
void ShoeDescription::setSize(int s)
{
m_size = s;
}
QColor ShoeDescription::color() const
{
return m_color;
}
void ShoeDescription::setColor(const QColor &c)
{
m_color = c;
}
QString ShoeDescription::brand() const
{
return m_brand;
}
void ShoeDescription::setBrand(const QString &b)
{
m_brand = b;
}
qreal ShoeDescription::price() const
{
return m_price;
}
void ShoeDescription::setPrice(qreal p)
{
m_price = p;
}
QString Person::name() const
{
return m_name;
}
void Person::setName(const QString &n)
{
m_name = n;
}
ShoeDescription *Person::shoe()
{
return &m_shoe;
}

View File

@ -1,39 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "birthdayparty.h"
// ![0]
Person *BirthdayParty::host() const
{
return m_host;
}
void BirthdayParty::setHost(Person *c)
{
m_host = c;
}
QQmlListProperty<Person> BirthdayParty::guests()
{
return {this, &m_guests};
}
qsizetype BirthdayParty::guestCount() const
{
return m_guests.count();
}
Person *BirthdayParty::guest(qsizetype index) const
{
return m_guests.at(index);
}
void BirthdayParty::invite(const QString &name)
{
auto *person = new Person(this);
person->setName(name);
m_guests.append(person);
}
// ![0]

View File

@ -1,36 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef BIRTHDAYPARTY_H
#define BIRTHDAYPARTY_H
#include <QObject>
#include <QQmlListProperty>
#include "person.h"
class BirthdayParty : public QObject
{
Q_OBJECT
Q_PROPERTY(Person *host READ host WRITE setHost)
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
QML_ELEMENT
public:
using QObject::QObject;
Person *host() const;
void setHost(Person *);
QQmlListProperty<Person> guests();
qsizetype guestCount() const;
Person *guest(qsizetype) const;
// ![0]
Q_INVOKABLE void invite(const QString &name);
// ![0]
private:
Person *m_host = nullptr;
QList<Person *> m_guests;
};
#endif // BIRTHDAYPARTY_H

View File

@ -1,21 +0,0 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
// ![0]
import QtQuick
import People
BirthdayParty {
host: Person {
name: "Bob Jones"
shoeSize: 12
}
guests: [
Person { name: "Leo Hodges" },
Person { name: "Jack Smith" },
Person { name: "Anne Brown" }
]
Component.onCompleted: invite("William Green")
}
// ![0]

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>example.qml</file>
</qresource>
</RCC>

View File

@ -1,24 +0,0 @@
// Copyright (C) 2021 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 &n)
{
m_name = n;
}
int Person::shoeSize() const
{
return m_shoeSize;
}
void Person::setShoeSize(int s)
{
m_shoeSize = s;
}

View File

@ -1,30 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef PERSON_H
#define PERSON_H
#include <QObject>
#include <QtQml/qqml.h>
class Person : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
QML_ELEMENT
public:
using QObject::QObject;
QString name() const;
void setName(const QString &);
int shoeSize() const;
void setShoeSize(int);
private:
QString m_name;
int m_shoeSize = 0;
};
#endif // PERSON_H

View File

@ -1,43 +0,0 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(properties LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/referenceexamples/properties")
find_package(Qt6 REQUIRED COMPONENTS Core Qml)
qt_add_executable(properties
birthdayparty.cpp birthdayparty.h
main.cpp
person.cpp person.h
)
set_target_properties(properties PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(properties PUBLIC
Qt::Core
Qt::Qml
)
qt_add_qml_module(properties
URI People
QML_FILES example.qml
NO_RESOURCE_TARGET_PATH
)
install(TARGETS properties
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -1,87 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "birthdayparty.h"
// ![0]
Person *BirthdayParty::host() const
{
return m_host;
}
void BirthdayParty::setHost(Person *c)
{
m_host = c;
}
QQmlListProperty<Person> BirthdayParty::guests()
{
return {this, this,
&BirthdayParty::appendGuest,
&BirthdayParty::guestCount,
&BirthdayParty::guest,
&BirthdayParty::clearGuests,
&BirthdayParty::replaceGuest,
&BirthdayParty::removeLastGuest};
}
void BirthdayParty::appendGuest(Person *p)
{
m_guests.append(p);
}
qsizetype BirthdayParty::guestCount() const
{
return m_guests.count();
}
Person *BirthdayParty::guest(qsizetype index) const
{
return m_guests.at(index);
}
void BirthdayParty::clearGuests() {
m_guests.clear();
}
void BirthdayParty::replaceGuest(qsizetype index, Person *p)
{
m_guests[index] = p;
}
void BirthdayParty::removeLastGuest()
{
m_guests.removeLast();
}
// ![0]
void BirthdayParty::appendGuest(QQmlListProperty<Person> *list, Person *p)
{
reinterpret_cast< BirthdayParty *>(list->data)->appendGuest(p);
}
void BirthdayParty::clearGuests(QQmlListProperty<Person>* list)
{
reinterpret_cast< BirthdayParty *>(list->data)->clearGuests();
}
void BirthdayParty::replaceGuest(QQmlListProperty<Person> *list, qsizetype i, Person *p)
{
reinterpret_cast< BirthdayParty* >(list->data)->replaceGuest(i, p);
}
void BirthdayParty::removeLastGuest(QQmlListProperty<Person> *list)
{
reinterpret_cast< BirthdayParty* >(list->data)->removeLastGuest();
}
Person* BirthdayParty::guest(QQmlListProperty<Person> *list, qsizetype i)
{
return reinterpret_cast< BirthdayParty* >(list->data)->guest(i);
}
qsizetype BirthdayParty::guestCount(QQmlListProperty<Person> *list)
{
return reinterpret_cast< BirthdayParty* >(list->data)->guestCount();
}

View File

@ -1,28 +0,0 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QCoreApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QDebug>
#include "birthdayparty.h"
#include "person.h"
int main(int argc, char ** argv)
{
QCoreApplication app(argc, argv);
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
auto *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;
}

View File

@ -1,24 +0,0 @@
// Copyright (C) 2021 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 &n)
{
m_name = n;
}
int Person::shoeSize() const
{
return m_shoeSize;
}
void Person::setShoeSize(int s)
{
m_shoeSize = s;
}

View File

@ -1,30 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef PERSON_H
#define PERSON_H
#include <QObject>
#include <QtQml/qqml.h>
class Person : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
QML_ELEMENT
public:
using QObject::QObject;
QString name() const;
void setName(const QString &);
int shoeSize() const;
void setShoeSize(int);
private:
QString m_name;
int m_shoeSize = 0;
};
#endif // PERSON_H

View File

@ -1,15 +0,0 @@
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 += properties.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/qml/referenceexamples/properties
INSTALLS += target

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>example.qml</file>
</qresource>
</RCC>

View File

@ -1,17 +0,0 @@
TEMPLATE = subdirs
SUBDIRS += \
adding \
coercion \
default \
properties \
methods
qtHaveModule(widgets): SUBDIRS += extended
qtHaveModule(quick): SUBDIRS += \
attached \
binding \
grouped \
signal \
valuesource

View File

@ -1,14 +0,0 @@
import QmlProject 1.0
Project {
/* Include .qml, .js, and image files from current directory and subdirectories */
QmlFiles {
directory: "."
}
JavaScriptFiles {
directory: "."
}
ImageFiles {
directory: "."
}
}

View File

@ -1,44 +0,0 @@
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(signal LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/referenceexamples/signal")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml)
qt_add_executable(signal
birthdayparty.cpp birthdayparty.h
main.cpp
person.cpp person.h
)
set_target_properties(signal PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(signal PUBLIC
Qt::Core
Qt::Gui
Qt::Qml
)
qt_add_qml_module(signal
URI People
QML_FILES example.qml
NO_RESOURCE_TARGET_PATH
)
install(TARGETS signal
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

View File

@ -1,51 +0,0 @@
// Copyright (C) 2021 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 d)
{
m_rsvp = d;
}
Person *BirthdayParty::host() const
{
return m_host;
}
void BirthdayParty::setHost(Person *c)
{
m_host = c;
}
QQmlListProperty<Person> BirthdayParty::guests()
{
return {this, &m_guests};
}
qsizetype BirthdayParty::guestCount() const
{
return m_guests.count();
}
Person *BirthdayParty::guest(qsizetype index) const
{
return m_guests.at(index);
}
void BirthdayParty::startParty()
{
QTime time = QTime::currentTime();
emit partyStarted(time);
}
BirthdayPartyAttached *BirthdayParty::qmlAttachedProperties(QObject *object)
{
return new BirthdayPartyAttached(object);
}

View File

@ -1,57 +0,0 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef BIRTHDAYPARTY_H
#define BIRTHDAYPARTY_H
#include <QObject>
#include <QDate>
#include <qqml.h>
#include "person.h"
class BirthdayPartyAttached : public QObject
{
Q_OBJECT
Q_PROPERTY(QDate rsvp READ rsvp WRITE setRsvp)
QML_ANONYMOUS
public:
using QObject::QObject;
QDate rsvp() const;
void setRsvp(QDate);
private:
QDate m_rsvp;
};
class BirthdayParty : public QObject
{
Q_OBJECT
Q_PROPERTY(Person *host READ host WRITE setHost)
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
Q_CLASSINFO("DefaultProperty", "guests")
QML_ELEMENT
QML_ATTACHED(BirthdayPartyAttached)
public:
using QObject::QObject;
Person *host() const;
void setHost(Person *);
QQmlListProperty<Person> guests();
qsizetype guestCount() const;
Person *guest(qsizetype) const;
static BirthdayPartyAttached *qmlAttachedProperties(QObject *);
void startParty();
// ![0]
signals:
void partyStarted(QTime time);
// ![0]
private:
Person *m_host = nullptr;
QList<Person *> m_guests;
};
#endif // BIRTHDAYPARTY_H

View File

@ -1,36 +0,0 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import People
import QtQuick // For QColor
BirthdayParty {
// ![0]
onPartyStarted: (time) => { console.log("This party started rockin' at " + time); }
// ![0]
host: Boy {
name: "Bob Jones"
shoe { size: 12; color: "white"; brand: "Nike"; price: 90.0 }
}
Boy {
name: "Leo Hodges"
BirthdayParty.rsvp: "2009-07-06"
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: "2009-07-01"
shoe.size: 7
shoe.color: "red"
shoe.brand: "Marc Jacobs"
shoe.price: 699.99
}
// ![1]
}
// ![1]

View File

@ -1,47 +0,0 @@
// Copyright (C) 2017 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QCoreApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QDebug>
#include "birthdayparty.h"
#include "person.h"
int main(int argc, char ** argv)
{
QCoreApplication app(argc, argv);
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
auto *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 EXIT_SUCCESS;
}
qWarning() << component.errors();
return EXIT_FAILURE;
}

View File

@ -1,59 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "person.h"
int ShoeDescription::size() const
{
return m_size;
}
void ShoeDescription::setSize(int s)
{
m_size = s;
}
QColor ShoeDescription::color() const
{
return m_color;
}
void ShoeDescription::setColor(const QColor &c)
{
m_color = c;
}
QString ShoeDescription::brand() const
{
return m_brand;
}
void ShoeDescription::setBrand(const QString &b)
{
m_brand = b;
}
qreal ShoeDescription::price() const
{
return m_price;
}
void ShoeDescription::setPrice(qreal p)
{
m_price = p;
}
QString Person::name() const
{
return m_name;
}
void Person::setName(const QString &n)
{
m_name = n;
}
ShoeDescription *Person::shoe()
{
return &m_shoe;
}

View File

@ -1,15 +0,0 @@
QT += 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 += signal.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/qml/referenceexamples/signal
INSTALLS += target

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>example.qml</file>
</qresource>
</RCC>

View File

@ -1,60 +0,0 @@
// Copyright (C) 2021 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 d)
{
m_rsvp = d;
}
Person *BirthdayParty::host() const
{
return m_host;
}
void BirthdayParty::setHost(Person *c)
{
m_host = c;
}
QQmlListProperty<Person> BirthdayParty::guests()
{
return {this, &m_guests};
}
qsizetype BirthdayParty::guestCount() const
{
return m_guests.count();
}
Person *BirthdayParty::guest(qsizetype index) const
{
return m_guests.at(index);
}
void BirthdayParty::startParty()
{
QTime time = QTime::currentTime();
emit partyStarted(time);
}
QString BirthdayParty::announcement() const
{
return QString();
}
void BirthdayParty::setAnnouncement(const QString &speak)
{
qInfo().noquote() << speak;
}
BirthdayPartyAttached *BirthdayParty::qmlAttachedProperties(QObject *object)
{
return new BirthdayPartyAttached(object);
}

View File

@ -1,59 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include "person.h"
int ShoeDescription::size() const
{
return m_size;
}
void ShoeDescription::setSize(int s)
{
m_size = s;
}
QColor ShoeDescription::color() const
{
return m_color;
}
void ShoeDescription::setColor(const QColor &c)
{
m_color = c;
}
QString ShoeDescription::brand() const
{
return m_brand;
}
void ShoeDescription::setBrand(const QString &b)
{
m_brand = b;
}
qreal ShoeDescription::price() const
{
return m_price;
}
void ShoeDescription::setPrice(qreal p)
{
m_price = p;
}
QString Person::name() const
{
return m_name;
}
void Person::setName(const QString &n)
{
m_name = n;
}
ShoeDescription *Person::shoe()
{
return &m_shoe;
}

View File

@ -1,77 +0,0 @@
// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef PERSON_H
#define PERSON_H
#include <QObject>
#include <QColor>
#include <QtQml/qqml.h>
class ShoeDescription : public QObject
{
Q_OBJECT
Q_PROPERTY(int size READ size WRITE setSize)
Q_PROPERTY(QColor color READ color WRITE setColor)
Q_PROPERTY(QString brand READ brand WRITE setBrand)
Q_PROPERTY(qreal price READ price WRITE setPrice)
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);
private:
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)
// ![1]
Q_PROPERTY(ShoeDescription *shoe READ shoe)
// ![1]
QML_ANONYMOUS
public:
using QObject::QObject;
QString name() const;
void setName(const QString &);
ShoeDescription *shoe();
private:
QString m_name;
ShoeDescription m_shoe;
};
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

View File

@ -1,5 +0,0 @@
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>example.qml</file>
</qresource>
</RCC>

View File

@ -0,0 +1,10 @@
# Copyright (C) 2023 The Qt Company Ltd.
# SPDX-License-Identifier: BSD-3-Clause
qt_internal_add_example(advanced1-Base-project)
qt_internal_add_example(advanced2-Inheritance-and-coercion)
qt_internal_add_example(advanced3-Default-properties)
qt_internal_add_example(advanced4-Grouped-properties)
qt_internal_add_example(advanced5-Attached-properties)
qt_internal_add_example(advanced6-Property-value-source)
qt_internal_add_example(advanced7-Extension-objects)

View File

@ -2,41 +2,41 @@
# SPDX-License-Identifier: BSD-3-Clause
cmake_minimum_required(VERSION 3.16)
project(methods LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
project(baseproject LANGUAGES CXX)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/referenceexamples/methods")
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_add_executable(methods
qt_policy(SET QTP0001 NEW)
qt_add_executable(baseproject
birthdayparty.cpp birthdayparty.h
main.cpp
person.cpp person.h
)
set_target_properties(methods PROPERTIES
set_target_properties(baseproject PROPERTIES
WIN32_EXECUTABLE TRUE
MACOSX_BUNDLE TRUE
)
target_link_libraries(methods PUBLIC
target_link_libraries(baseproject PUBLIC
Qt::Core
Qt::Qml
)
qt_add_qml_module(methods
qt_add_qml_module(baseproject
URI People
QML_FILES example.qml
NO_RESOURCE_TARGET_PATH
QML_FILES Main.qml
)
install(TARGETS methods
install(TARGETS baseproject
RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"

View File

@ -1,9 +1,8 @@
// Copyright (C) 2017 The Qt Company Ltd.
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import People
// ![0]
BirthdayParty {
host: Person {
name: "Bob Jones"
@ -15,4 +14,3 @@ BirthdayParty {
Person { name: "Anne Brown" }
]
}
// ![0]

View File

@ -9,7 +9,5 @@ SOURCES += main.cpp \
birthdayparty.cpp
HEADERS += person.h \
birthdayparty.h
RESOURCES += methods.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/qml/referenceexamples/methods
INSTALLS += target
RESOURCES += baseproject.qrc

View File

@ -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>

View File

@ -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();
}

View File

@ -1,26 +1,19 @@
// Copyright (C) 2021 The Qt Company Ltd.
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef BIRTHDAYPARTY_H
#define BIRTHDAYPARTY_H
#include <QObject>
#include <QList>
#include <QQmlListProperty>
#include "person.h"
// ![0]
#include <QObject>
#include <QQmlListProperty>
class BirthdayParty : public QObject
{
Q_OBJECT
// ![0]
// ![1]
Q_PROPERTY(Person *host READ host WRITE setHost)
// ![1]
// ![2]
Q_PROPERTY(QQmlListProperty<Person> guests READ guests)
// ![2]
// ![3]
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;
@ -36,10 +29,14 @@ public:
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 Person *guest(QQmlListProperty<Person> *, qsizetype);
static void clearGuests(QQmlListProperty<Person> *);
static void replaceGuest(QQmlListProperty<Person> *, qsizetype, Person *);
static void removeLastGuest(QQmlListProperty<Person> *);
@ -47,6 +44,5 @@ private:
Person *m_host = nullptr;
QList<Person *> m_guests;
};
// ![3]
#endif // BIRTHDAYPARTY_H

View File

@ -1,24 +1,27 @@
// Copyright (C) 2021 The Qt Company Ltd.
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QCoreApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QDebug>
#include "birthdayparty.h"
#include "person.h"
int main(int argc, char ** argv)
#include <QCoreApplication>
#include <QDebug>
#include <QQmlComponent>
#include <QQmlEngine>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
auto *party = qobject_cast<BirthdayParty *>(component.create());
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!"
<< "\nThey are inviting:";
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;

View File

@ -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();
}
}

View File

@ -1,18 +1,17 @@
// Copyright (C) 2021 The Qt Company Ltd.
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef PERSON_H
#define PERSON_H
#include <QObject>
#include <QtQml/qqml.h>
#include <QObject>
//![0]
class Person : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
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;
@ -23,10 +22,13 @@ public:
int shoeSize() const;
void setShoeSize(int);
signals:
void nameChanged();
void shoeSizeChanged();
private:
QString m_name;
int m_shoeSize = 0;
};
//![0]
#endif // PERSON_H

View File

@ -0,0 +1,4 @@
module People
typeinfo birthdayparty.qmltypes
prefer :/qt/qml/People/
Main 254.0 Main.qml

View File

@ -4,15 +4,16 @@
cmake_minimum_required(VERSION 3.16)
project(coercion LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/referenceexamples/coercion")
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/tutorials/extending-qml-advanced/advanced2-Inheritance-and-coercion")
find_package(Qt6 REQUIRED COMPONENTS Core Qml)
qt_standard_project_setup()
qt_policy(SET QTP0001 NEW)
qt_add_executable(coercion
birthdayparty.cpp birthdayparty.h
@ -32,8 +33,7 @@ target_link_libraries(coercion PUBLIC
qt_add_qml_module(coercion
URI People
QML_FILES example.qml
NO_RESOURCE_TARGET_PATH
QML_FILES Main.qml
)
install(TARGETS coercion

View File

@ -1,9 +1,8 @@
// Copyright (C) 2017 The Qt Company Ltd.
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import People
// ![0]
BirthdayParty {
host: Boy {
name: "Bob Jones"
@ -15,4 +14,3 @@ BirthdayParty {
Girl { name: "Anne Brown" }
]
}
// ![0]

View File

@ -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();
}

View File

@ -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> *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

View File

@ -10,6 +10,3 @@ SOURCES += main.cpp \
HEADERS += person.h \
birthdayparty.h
RESOURCES += coercion.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/qml/referenceexamples/coercion
INSTALLS += target

View File

@ -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>

View File

@ -1,20 +1,22 @@
// Copyright (C) 2021 The Qt Company Ltd.
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QCoreApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QDebug>
#include "birthdayparty.h"
#include "person.h"
int main(int argc, char ** argv)
#include <QCoreApplication>
#include <QDebug>
#include <QQmlComponent>
#include <QQmlEngine>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
auto *party = qobject_cast<BirthdayParty *>(component.create());
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!";

View File

@ -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();
}
}

View File

@ -1,21 +1,19 @@
// Copyright (C) 2021 The Qt Company Ltd.
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef PERSON_H
#define PERSON_H
#include <QObject>
#include <QtQml/qqml.h>
#include <QObject>
class Person : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
//![0]
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.")
//![0]
public:
using QObject::QObject;
@ -25,12 +23,15 @@ public:
int shoeSize() const;
void setShoeSize(int);
signals:
void nameChanged();
void shoeSizeChanged();
private:
QString m_name;
int m_shoeSize = 0;
};
// ![1]
class Boy : public Person
{
Q_OBJECT
@ -39,7 +40,6 @@ public:
using Person::Person;
};
//! [girl class]
class Girl : public Person
{
Q_OBJECT
@ -47,8 +47,5 @@ class Girl : public Person
public:
using Person::Person;
};
//! [girl class]
// ![1]
#endif // PERSON_H

View File

@ -0,0 +1,4 @@
module People
typeinfo coercion.qmltypes
prefer :/qt/qml/People/
Main 254.0 Main.qml

View File

@ -4,15 +4,16 @@
cmake_minimum_required(VERSION 3.16)
project(default LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/referenceexamples/default")
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
@ -32,8 +33,7 @@ target_link_libraries(default PUBLIC
qt_add_qml_module(default
URI People
QML_FILES example.qml
NO_RESOURCE_TARGET_PATH
QML_FILES Main.qml
)
install(TARGETS default

View File

@ -1,9 +1,8 @@
// Copyright (C) 2017 The Qt Company Ltd.
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import People
// ![0]
BirthdayParty {
host: Boy {
name: "Bob Jones"
@ -14,4 +13,3 @@ BirthdayParty {
Boy { name: "Jack Smith" }
Girl { name: "Anne Brown" }
}
// ![0]

View File

@ -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();
}

View File

@ -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

View File

@ -10,6 +10,3 @@ SOURCES += main.cpp \
HEADERS += person.h \
birthdayparty.h
RESOURCES += default.qrc
target.path = $$[QT_INSTALL_EXAMPLES]/qml/referenceexamples/default
INSTALLS += target

View File

@ -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>

View File

@ -1,19 +1,22 @@
// Copyright (C) 2017 The Qt Company Ltd.
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#include <QCoreApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QDebug>
#include "birthdayparty.h"
#include "person.h"
int main(int argc, char ** argv)
#include <QCoreApplication>
#include <QDebug>
#include <QQmlComponent>
#include <QQmlEngine>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QQmlEngine engine;
QQmlComponent component(&engine, QUrl("qrc:example.qml"));
auto *party = qobject_cast<BirthdayParty *>(component.create());
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!";

View File

@ -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();
}
}

View File

@ -1,18 +1,19 @@
// Copyright (C) 2021 The Qt Company Ltd.
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
#ifndef PERSON_H
#define PERSON_H
#include <QObject>
#include <QtQml/qqml.h>
#include <QObject>
class Person : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int shoeSize READ shoeSize WRITE setShoeSize)
QML_ANONYMOUS
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;
@ -21,6 +22,11 @@ public:
int shoeSize() const;
void setShoeSize(int);
signals:
void nameChanged();
void shoeSizeChanged();
private:
QString m_name;
int m_shoeSize = 0;

View File

@ -0,0 +1,4 @@
module People
typeinfo default.qmltypes
prefer :/qt/qml/People/
Main 254.0 Main.qml

View File

@ -4,15 +4,16 @@
cmake_minimum_required(VERSION 3.16)
project(grouped LANGUAGES CXX)
set(CMAKE_AUTOMOC ON)
if(NOT DEFINED INSTALL_EXAMPLESDIR)
set(INSTALL_EXAMPLESDIR "examples")
endif()
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/referenceexamples/grouped")
set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/qml/tutorials/extending-qml-advanced/advanced4-Grouped-properties")
find_package(Qt6 REQUIRED COMPONENTS Core Gui Qml)
find_package(Qt6 REQUIRED COMPONENTS Core Qml Gui)
qt_standard_project_setup()
qt_policy(SET QTP0001 NEW)
qt_add_executable(grouped
birthdayparty.cpp birthdayparty.h
@ -27,14 +28,15 @@ set_target_properties(grouped PROPERTIES
target_link_libraries(grouped PUBLIC
Qt::Core
Qt::Gui
Qt::Qml
Qt::Gui
)
qt_add_qml_module(grouped
URI People
QML_FILES example.qml
NO_RESOURCE_TARGET_PATH
QML_FILES Main.qml
DEPENDENCIES
QtQuick
)
install(TARGETS grouped

View File

@ -1,10 +1,9 @@
// Copyright (C) 2017 The Qt Company Ltd.
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import People
import QtQuick // For QColor
// ![0]
BirthdayParty {
host: Boy {
name: "Bob Jones"
@ -13,11 +12,8 @@ BirthdayParty {
Boy {
name: "Leo Hodges"
//![grouped]
shoe { size: 10; color: "black"; brand: "Thebok"; price: 59.95 }
//![grouped]
}
// ![1]
Boy {
name: "Jack Smith"
shoe {
@ -27,15 +23,11 @@ BirthdayParty {
price: 19.95
}
}
// ![1]
Girl {
name: "Anne Brown"
//![ungrouped]
shoe.size: 7
shoe.color: "red"
shoe.brand: "Job Macobs"
shoe.price: 699.99
//![ungrouped]
shoe.price: 99.99
}
}
// ![0]

View File

@ -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();
}

Some files were not shown because too many files have changed in this diff Show More