aboutsummaryrefslogtreecommitdiffstats
path: root/examples/qml/referenceexamples
diff options
context:
space:
mode:
Diffstat (limited to 'examples/qml/referenceexamples')
-rw-r--r--examples/qml/referenceexamples/adding/adding.pyproject5
-rw-r--r--examples/qml/referenceexamples/adding/doc/adding.rst67
-rw-r--r--examples/qml/referenceexamples/adding/example.qml9
-rw-r--r--examples/qml/referenceexamples/adding/main.py30
-rw-r--r--examples/qml/referenceexamples/adding/person.py35
-rw-r--r--examples/qml/referenceexamples/attached/attached.pyproject3
-rw-r--r--examples/qml/referenceexamples/attached/birthdayparty.py63
-rw-r--r--examples/qml/referenceexamples/attached/doc/attached.rst12
-rw-r--r--examples/qml/referenceexamples/attached/example.qml22
-rw-r--r--examples/qml/referenceexamples/attached/main.py46
-rw-r--r--examples/qml/referenceexamples/attached/person.py46
-rw-r--r--examples/qml/referenceexamples/binding/binding.pyproject3
-rw-r--r--examples/qml/referenceexamples/binding/birthdayparty.py83
-rw-r--r--examples/qml/referenceexamples/binding/doc/binding.rst17
-rw-r--r--examples/qml/referenceexamples/binding/example.qml29
-rw-r--r--examples/qml/referenceexamples/binding/happybirthdaysong.py47
-rw-r--r--examples/qml/referenceexamples/binding/main.py52
-rw-r--r--examples/qml/referenceexamples/binding/person.py53
-rw-r--r--examples/qml/referenceexamples/coercion/birthdayparty.py41
-rw-r--r--examples/qml/referenceexamples/coercion/coercion.pyproject3
-rw-r--r--examples/qml/referenceexamples/coercion/doc/coercion.rst35
-rw-r--r--examples/qml/referenceexamples/coercion/example.qml16
-rw-r--r--examples/qml/referenceexamples/coercion/main.py36
-rw-r--r--examples/qml/referenceexamples/coercion/person.py47
-rw-r--r--examples/qml/referenceexamples/default/birthdayparty.py42
-rw-r--r--examples/qml/referenceexamples/default/default.pyproject3
-rw-r--r--examples/qml/referenceexamples/default/doc/default.rst30
-rw-r--r--examples/qml/referenceexamples/default/example.qml15
-rw-r--r--examples/qml/referenceexamples/default/main.py36
-rw-r--r--examples/qml/referenceexamples/default/person.py46
-rw-r--r--examples/qml/referenceexamples/extended/doc/extended.rst41
-rw-r--r--examples/qml/referenceexamples/extended/example.qml8
-rw-r--r--examples/qml/referenceexamples/extended/extended.pyproject3
-rw-r--r--examples/qml/referenceexamples/extended/main.py95
-rw-r--r--examples/qml/referenceexamples/grouped/birthdayparty.py42
-rw-r--r--examples/qml/referenceexamples/grouped/doc/grouped.rst17
-rw-r--r--examples/qml/referenceexamples/grouped/example.qml33
-rw-r--r--examples/qml/referenceexamples/grouped/grouped.pyproject3
-rw-r--r--examples/qml/referenceexamples/grouped/main.py43
-rw-r--r--examples/qml/referenceexamples/grouped/person.py85
-rw-r--r--examples/qml/referenceexamples/methods/birthdayparty.py47
-rw-r--r--examples/qml/referenceexamples/methods/doc/methods.rst15
-rw-r--r--examples/qml/referenceexamples/methods/example.qml19
-rw-r--r--examples/qml/referenceexamples/methods/main.py32
-rw-r--r--examples/qml/referenceexamples/methods/methods.pyproject3
-rw-r--r--examples/qml/referenceexamples/methods/person.py34
-rw-r--r--examples/qml/referenceexamples/properties/birthdayparty.py41
-rw-r--r--examples/qml/referenceexamples/properties/doc/properties.rst89
-rw-r--r--examples/qml/referenceexamples/properties/example.qml16
-rw-r--r--examples/qml/referenceexamples/properties/main.py34
-rw-r--r--examples/qml/referenceexamples/properties/person.py35
-rw-r--r--examples/qml/referenceexamples/properties/properties.pyproject6
-rw-r--r--examples/qml/referenceexamples/valuesource/birthdayparty.py76
-rw-r--r--examples/qml/referenceexamples/valuesource/doc/valuesource.rst20
-rw-r--r--examples/qml/referenceexamples/valuesource/example.qml27
-rw-r--r--examples/qml/referenceexamples/valuesource/happybirthdaysong.py47
-rw-r--r--examples/qml/referenceexamples/valuesource/main.py51
-rw-r--r--examples/qml/referenceexamples/valuesource/person.py46
-rw-r--r--examples/qml/referenceexamples/valuesource/valuesource.pyproject3
59 files changed, 1983 insertions, 0 deletions
diff --git a/examples/qml/referenceexamples/adding/adding.pyproject b/examples/qml/referenceexamples/adding/adding.pyproject
new file mode 100644
index 000000000..46df4b253
--- /dev/null
+++ b/examples/qml/referenceexamples/adding/adding.pyproject
@@ -0,0 +1,5 @@
+{
+ "files": ["example.qml",
+ "main.py",
+ "person.py"]
+}
diff --git a/examples/qml/referenceexamples/adding/doc/adding.rst b/examples/qml/referenceexamples/adding/doc/adding.rst
new file mode 100644
index 000000000..55f6105b7
--- /dev/null
+++ b/examples/qml/referenceexamples/adding/doc/adding.rst
@@ -0,0 +1,67 @@
+.. _qml-adding-types-example:
+
+Extending QML - Adding Types Example
+====================================
+
+The Adding Types Example shows how to add a new object type, ``Person``, to QML.
+The ``Person`` type can be used from QML like this:
+
+.. code-block:: javascript
+
+ import examples.adding.people
+
+ Person {
+ name: "Bob Jones"
+ shoe_size: 12
+ }
+
+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.
+
+The Person class implementation is quite basic. The property accessors simply
+return members of the object instance.
+
+.. code-block:: python
+
+ from PySide6.QtCore import QObject, Property
+ from PySide6.QtQml import QmlElement
+
+ # To be used on the @QmlElement decorator
+ # (QML_IMPORT_MINOR_VERSION is optional)
+ QML_IMPORT_NAME = "examples.adding.people"
+ QML_IMPORT_MAJOR_VERSION = 1
+
+
+ @QmlElement
+ class Person(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._name = ''
+ self._shoe_size = 0
+
+ @Property(str)
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, n):
+ self._name = n
+
+ @Property(int)
+ def shoe_size(self):
+ return self._shoe_size
+
+ @shoe_size.setter
+ def shoe_size(self, s):
+ self._shoe_size = s
+
+Running the Example
+-------------------
+
+The main.py file in the example includes a simple shell application that
+loads and runs the QML snippet shown at the beginning of this page.
diff --git a/examples/qml/referenceexamples/adding/example.qml b/examples/qml/referenceexamples/adding/example.qml
new file mode 100644
index 000000000..42d47dea9
--- /dev/null
+++ b/examples/qml/referenceexamples/adding/example.qml
@@ -0,0 +1,9 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import examples.adding.people
+
+Person {
+ name: "Bob Jones"
+ shoe_size: 12
+}
diff --git a/examples/qml/referenceexamples/adding/main.py b/examples/qml/referenceexamples/adding/main.py
new file mode 100644
index 000000000..f10b77bc1
--- /dev/null
+++ b/examples/qml/referenceexamples/adding/main.py
@@ -0,0 +1,30 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 port of the qml/examples/qml/referenceexamples/adding example from Qt v6.x"""
+
+from pathlib import Path
+import sys
+
+from PySide6.QtCore import QCoreApplication, QUrl
+from PySide6.QtQml import QQmlComponent, QQmlEngine
+
+from person import Person
+
+
+if __name__ == '__main__':
+ app = QCoreApplication(sys.argv)
+
+ qml_file = Path(__file__).parent / "example.qml"
+ url = QUrl.fromLocalFile(qml_file)
+ engine = QQmlEngine()
+ component = QQmlComponent(engine, url)
+
+ person = component.create()
+ if person:
+ print(f"The person's name is {person.name}")
+ print(f"They wear a {person.shoe_size} sized shoe")
+ else:
+ print(component.errors())
+ del engine
+ sys.exit(0)
diff --git a/examples/qml/referenceexamples/adding/person.py b/examples/qml/referenceexamples/adding/person.py
new file mode 100644
index 000000000..0c2b5b124
--- /dev/null
+++ b/examples/qml/referenceexamples/adding/person.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, Property
+from PySide6.QtQml import QmlElement
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.adding.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class Person(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._name = ''
+ self._shoe_size = 0
+
+ @Property(str)
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, n):
+ self._name = n
+
+ @Property(int)
+ def shoe_size(self):
+ return self._shoe_size
+
+ @shoe_size.setter
+ def shoe_size(self, s):
+ self._shoe_size = s
+
diff --git a/examples/qml/referenceexamples/attached/attached.pyproject b/examples/qml/referenceexamples/attached/attached.pyproject
new file mode 100644
index 000000000..3c01c40c2
--- /dev/null
+++ b/examples/qml/referenceexamples/attached/attached.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py", "birthdayparty.py", "person.py", "example.qml"]
+}
diff --git a/examples/qml/referenceexamples/attached/birthdayparty.py b/examples/qml/referenceexamples/attached/birthdayparty.py
new file mode 100644
index 000000000..d83236e26
--- /dev/null
+++ b/examples/qml/referenceexamples/attached/birthdayparty.py
@@ -0,0 +1,63 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QDate, QObject, ClassInfo, Property
+from PySide6.QtQml import QmlAnonymous, QmlAttached, QmlElement, ListProperty
+
+from person import Person
+
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.default.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlAnonymous
+class BirthdayPartyAttached(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._rsvp = QDate()
+
+ @Property(QDate)
+ def rsvp(self):
+ return self._rsvp
+
+ @rsvp.setter
+ def rsvp(self, d):
+ self._rsvp = d
+
+
+@QmlElement
+@ClassInfo(DefaultProperty="guests")
+@QmlAttached(BirthdayPartyAttached)
+class BirthdayParty(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._host = None
+ self._guests = []
+
+ @Property(Person)
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, h):
+ self._host = h
+
+ def guest(self, n):
+ return self._guests[n]
+
+ def guestCount(self):
+ return len(self._guests)
+
+ def appendGuest(self, guest):
+ self._guests.append(guest)
+
+ @staticmethod
+ def qmlAttachedProperties(self, o):
+ return BirthdayPartyAttached(o)
+
+ guests = ListProperty(Person, appendGuest)
diff --git a/examples/qml/referenceexamples/attached/doc/attached.rst b/examples/qml/referenceexamples/attached/doc/attached.rst
new file mode 100644
index 000000000..95fb5c43c
--- /dev/null
+++ b/examples/qml/referenceexamples/attached/doc/attached.rst
@@ -0,0 +1,12 @@
+.. _qml-attached-properties-example:
+
+Extending QML - Attached Properties Example
+===========================================
+
+This example builds on the :ref:`qml-default-property-example`,
+:ref:`qml-inheritance-and-coercion-example`,
+:ref:`qml-object-and-list-property-types-example`
+and the :ref:`qml-adding-types-example`.
+
+The Attached Properties Example example shows how to inject
+properties to child objects.
diff --git a/examples/qml/referenceexamples/attached/example.qml b/examples/qml/referenceexamples/attached/example.qml
new file mode 100644
index 000000000..f038b3ece
--- /dev/null
+++ b/examples/qml/referenceexamples/attached/example.qml
@@ -0,0 +1,22 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import examples.default.people
+
+BirthdayParty {
+ Boy {
+ name: "Robert Campbell"
+ BirthdayParty.rsvp: "2009-07-01"
+ }
+
+ Boy {
+ name: "Leo Hodges"
+ shoe_size: 10
+ BirthdayParty.rsvp: "2009-07-06"
+ }
+
+ host: Boy {
+ name: "Jack Smith"
+ shoe_size: 8
+ }
+}
diff --git a/examples/qml/referenceexamples/attached/main.py b/examples/qml/referenceexamples/attached/main.py
new file mode 100644
index 000000000..d7483559f
--- /dev/null
+++ b/examples/qml/referenceexamples/attached/main.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 port of the qml/examples/qml/referenceexamples/attached example from Qt v6.x"""
+
+from pathlib import Path
+import sys
+
+from PySide6.QtCore import QCoreApplication, QUrl
+from PySide6.QtQml import QQmlComponent, QQmlEngine, qmlAttachedPropertiesObject
+
+from person import Boy, Girl
+from birthdayparty import BirthdayParty
+
+
+app = QCoreApplication(sys.argv)
+qml_file = Path(__file__).parent / "example.qml"
+url = QUrl.fromLocalFile(qml_file)
+engine = QQmlEngine()
+component = QQmlComponent(engine, url)
+party = component.create()
+if not party:
+ print(component.errors())
+ del engine
+ sys.exit(-1)
+host = party.host
+print(f"{host.name} is having a birthday!")
+if isinstance(host, Boy):
+ print("He is inviting:")
+else:
+ print("She is inviting:")
+for g in range(party.guestCount()):
+ guest = party.guest(g)
+ name = guest.name
+
+ rsvp_date = None
+ attached = qmlAttachedPropertiesObject(BirthdayParty, guest, False)
+ if attached:
+ rsvp_date = attached.rsvp.toString()
+ if rsvp_date:
+ print(f" {name} RSVP date: {rsvp_date}")
+ else:
+ print(f" {name} RSVP date: Hasn't RSVP'd")
+
+del engine
+sys.exit(0)
diff --git a/examples/qml/referenceexamples/attached/person.py b/examples/qml/referenceexamples/attached/person.py
new file mode 100644
index 000000000..7164bd645
--- /dev/null
+++ b/examples/qml/referenceexamples/attached/person.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, Property
+from PySide6.QtQml import QmlAnonymous, QmlElement
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.default.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlAnonymous
+class Person(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._name = ''
+ self._shoe_size = 0
+
+ @Property(str)
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, n):
+ self._name = n
+
+ @Property(int)
+ def shoe_size(self):
+ return self._shoe_size
+
+ @shoe_size.setter
+ def shoe_size(self, s):
+ self._shoe_size = s
+
+
+@QmlElement
+class Boy(Person):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+
+@QmlElement
+class Girl(Person):
+ def __init__(self, parent=None):
+ super().__init__(parent)
diff --git a/examples/qml/referenceexamples/binding/binding.pyproject b/examples/qml/referenceexamples/binding/binding.pyproject
new file mode 100644
index 000000000..a782d5c8a
--- /dev/null
+++ b/examples/qml/referenceexamples/binding/binding.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py", "birthdayparty.py", "happybirthdaysong.py", "person.py", "example.qml"]
+}
diff --git a/examples/qml/referenceexamples/binding/birthdayparty.py b/examples/qml/referenceexamples/binding/birthdayparty.py
new file mode 100644
index 000000000..78f0314b4
--- /dev/null
+++ b/examples/qml/referenceexamples/binding/birthdayparty.py
@@ -0,0 +1,83 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QDate, QObject, ClassInfo, Property, QTime, Signal
+from PySide6.QtQml import QmlAnonymous, QmlAttached, QmlElement, ListProperty
+
+from person import Person
+
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.binding.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlAnonymous
+class BirthdayPartyAttached(QObject):
+
+ rsvp_changed = Signal()
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._rsvp = QDate()
+
+ @Property(QDate, notify=rsvp_changed)
+ def rsvp(self):
+ return self._rsvp
+
+ @rsvp.setter
+ def rsvp(self, d):
+ if self._rsvp != d:
+ self._rsvp = d
+ self.rsvp_changed.emit()
+
+
+@QmlElement
+@ClassInfo(DefaultProperty="guests")
+@QmlAttached(BirthdayPartyAttached)
+class BirthdayParty(QObject):
+
+ partyStarted = Signal(QTime)
+ host_changed = Signal()
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._host = None
+ self._guests = []
+
+ def startParty(self):
+ self.partyStarted.emit(QTime.currentTime())
+
+ @Property(Person, notify=host_changed)
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, h):
+ if self._host != h:
+ self._host = h
+ self.host_changed.emit()
+
+ @Property(str)
+ def announcement(self):
+ return ""
+
+ @announcement.setter
+ def announcement(self, a):
+ print(a)
+
+ def guest(self, n):
+ return self._guests[n]
+
+ def guestCount(self):
+ return len(self._guests)
+
+ def appendGuest(self, guest):
+ self._guests.append(guest)
+
+ @staticmethod
+ def qmlAttachedProperties(self, o):
+ return BirthdayPartyAttached(o)
+
+ guests = ListProperty(Person, appendGuest)
diff --git a/examples/qml/referenceexamples/binding/doc/binding.rst b/examples/qml/referenceexamples/binding/doc/binding.rst
new file mode 100644
index 000000000..5c0ed21be
--- /dev/null
+++ b/examples/qml/referenceexamples/binding/doc/binding.rst
@@ -0,0 +1,17 @@
+.. _qml-binding-example:
+
+Extending QML - Binding Example
+===============================
+
+This example builds on the :ref:`qml-adding-types-example`,
+the :ref:`qml-attached-properties-example`,
+the :ref:`qml-default-property-example`,
+the :ref:`qml-inheritance-and-coercion-example`
+the :ref:`qml-object-and-list-property-types-example`
+and the :ref:`qml-valuesource-example`.
+
+Running the Example
+-------------------
+
+The ``main.py`` file in the example includes a simple shell application that
+loads and runs the QML snippet shown below.
diff --git a/examples/qml/referenceexamples/binding/example.qml b/examples/qml/referenceexamples/binding/example.qml
new file mode 100644
index 000000000..ca0958810
--- /dev/null
+++ b/examples/qml/referenceexamples/binding/example.qml
@@ -0,0 +1,29 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import examples.binding.people
+
+BirthdayParty {
+ id: theParty
+
+ HappyBirthdaySong on announcement { name: theParty.host.name }
+
+ onPartyStarted: (time) => { console.log("This party started rockin' at " + time); }
+
+ host: Boy {
+ name: "Bob Jones"
+ shoe_size: 12
+ }
+
+ Boy {
+ name: "Leo Hodges"
+ BirthdayParty.rsvp: "2009-07-06"
+ }
+ Boy {
+ name: "Jack Smith"
+ }
+ Girl {
+ name: "Anne Brown"
+ BirthdayParty.rsvp: "2009-07-01"
+ }
+}
diff --git a/examples/qml/referenceexamples/binding/happybirthdaysong.py b/examples/qml/referenceexamples/binding/happybirthdaysong.py
new file mode 100644
index 000000000..cfe34eb82
--- /dev/null
+++ b/examples/qml/referenceexamples/binding/happybirthdaysong.py
@@ -0,0 +1,47 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, QTimer, Property, Slot
+from PySide6.QtQml import QmlElement, QPyQmlPropertyValueSource
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.binding.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class HappyBirthdaySong(QPyQmlPropertyValueSource):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ self.m_target = None
+ self.m_name = ""
+ self.m_line = -1
+ self.m_lyrics = []
+
+ self.m_timer = QTimer(self)
+ self.m_timer.timeout.connect(self.advance)
+ self.m_timer.start(1000)
+
+ def setTarget(self, property):
+ self.m_target = property
+
+ @Property(str)
+ def name(self):
+ return self.m_name
+
+ @name.setter
+ def name(self, n):
+ self.m_name = n
+ self.m_lyrics = ["Happy birthday to you,",
+ "Happy birthday to you,",
+ f"Happy birthday dear {self.m_name},",
+ "Happy birthday to you!",
+ ""]
+
+ @Slot()
+ def advance(self):
+ self.m_line = (self.m_line + 1) % len(self.m_lyrics)
+ self.m_target.write(self.m_lyrics[self.m_line])
diff --git a/examples/qml/referenceexamples/binding/main.py b/examples/qml/referenceexamples/binding/main.py
new file mode 100644
index 000000000..dcbd547ad
--- /dev/null
+++ b/examples/qml/referenceexamples/binding/main.py
@@ -0,0 +1,52 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 port of the qml/examples/qml/referenceexamples/binding example from Qt v6.x"""
+
+from pathlib import Path
+import sys
+
+from PySide6.QtCore import QCoreApplication, QUrl
+from PySide6.QtQml import QQmlComponent, QQmlEngine, qmlAttachedPropertiesObject
+
+from person import Boy, Girl
+from birthdayparty import BirthdayParty
+from happybirthdaysong import HappyBirthdaySong
+
+
+if __name__ == "__main__":
+ app = QCoreApplication(sys.argv)
+ qml_file = Path(__file__).parent / "example.qml"
+ url = QUrl.fromLocalFile(qml_file)
+ engine = QQmlEngine()
+ component = QQmlComponent(engine, url)
+ party = component.create()
+ if not party:
+ print(component.errors())
+ del engine
+ sys.exit(-1)
+ host = party.host
+ print(f"{host.name} is having a birthday!")
+ if isinstance(host, Boy):
+ print("He is inviting:")
+ else:
+ print("She is inviting:")
+ for g in range(party.guestCount()):
+ guest = party.guest(g)
+ name = guest.name
+
+ rsvp_date = None
+ attached = qmlAttachedPropertiesObject(BirthdayParty, guest, False)
+ if attached:
+ rsvp_date = attached.rsvp.toString()
+ if rsvp_date:
+ print(f" {name} RSVP date: {rsvp_date}")
+ else:
+ print(f" {name} RSVP date: Hasn't RSVP'd")
+
+ party.startParty()
+
+ r = app.exec()
+
+ del engine
+ sys.exit(r)
diff --git a/examples/qml/referenceexamples/binding/person.py b/examples/qml/referenceexamples/binding/person.py
new file mode 100644
index 000000000..9e7d799e1
--- /dev/null
+++ b/examples/qml/referenceexamples/binding/person.py
@@ -0,0 +1,53 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, Property, Signal
+from PySide6.QtQml import QmlAnonymous, QmlElement
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.binding.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlAnonymous
+class Person(QObject):
+ name_changed = Signal()
+ shoe_size_changed = Signal()
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._name = ''
+ self._shoe_size = 0
+
+ @Property(str, notify=name_changed)
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, n):
+ if self._name != n:
+ self._name = n
+ self.name_changed.emit()
+
+ @Property(int, notify=shoe_size_changed)
+ def shoe_size(self):
+ return self._shoe_size
+
+ @shoe_size.setter
+ def shoe_size(self, s):
+ if self._shoe_size != s:
+ self._shoe_size = s
+ self.shoe_size_changed.emit()
+
+
+@QmlElement
+class Boy(Person):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+
+@QmlElement
+class Girl(Person):
+ def __init__(self, parent=None):
+ super().__init__(parent)
diff --git a/examples/qml/referenceexamples/coercion/birthdayparty.py b/examples/qml/referenceexamples/coercion/birthdayparty.py
new file mode 100644
index 000000000..f6ad1ac35
--- /dev/null
+++ b/examples/qml/referenceexamples/coercion/birthdayparty.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, Property
+from PySide6.QtQml import QmlElement, ListProperty
+
+from person import Person
+
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.coercion.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class BirthdayParty(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._host = None
+ self._guests = []
+
+ @Property(Person)
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, h):
+ self._host = h
+
+ def guest(self, n):
+ return self._guests[n]
+
+ def guestCount(self):
+ return len(self._guests)
+
+ def appendGuest(self, guest):
+ self._guests.append(guest)
+
+ guests = ListProperty(Person, appendGuest)
diff --git a/examples/qml/referenceexamples/coercion/coercion.pyproject b/examples/qml/referenceexamples/coercion/coercion.pyproject
new file mode 100644
index 000000000..3c01c40c2
--- /dev/null
+++ b/examples/qml/referenceexamples/coercion/coercion.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py", "birthdayparty.py", "person.py", "example.qml"]
+}
diff --git a/examples/qml/referenceexamples/coercion/doc/coercion.rst b/examples/qml/referenceexamples/coercion/doc/coercion.rst
new file mode 100644
index 000000000..2ccdaeb4f
--- /dev/null
+++ b/examples/qml/referenceexamples/coercion/doc/coercion.rst
@@ -0,0 +1,35 @@
+.. _qml-inheritance-and-coercion-example:
+
+Extending QML - Inheritance and Coercion Example
+================================================
+
+This example builds on the :ref:`qml-adding-types-example` and the
+:ref:`qml-object-and-list-property-types-example` .
+
+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 ``Boy`` and a ``Girl``.
+
+Declare Boy and Girl
+--------------------
+
+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.
+
+Running the Example
+-------------------
+
+The BirthdayParty type has not changed since the previous example. The
+celebrant and guests property still use the People type.
+
+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.py file in the example includes a simple shell application that
+loads and runs the QML snippet shown below.
diff --git a/examples/qml/referenceexamples/coercion/example.qml b/examples/qml/referenceexamples/coercion/example.qml
new file mode 100644
index 000000000..c47678483
--- /dev/null
+++ b/examples/qml/referenceexamples/coercion/example.qml
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import examples.coercion.people
+
+BirthdayParty {
+ host: Boy {
+ name: "Bob Jones"
+ shoe_size: 12
+ }
+ guests: [
+ Boy { name: "Leo Hodges" },
+ Boy { name: "Jack Smith" },
+ Girl { name: "Anne Brown" }
+ ]
+}
diff --git a/examples/qml/referenceexamples/coercion/main.py b/examples/qml/referenceexamples/coercion/main.py
new file mode 100644
index 000000000..9f49bc1da
--- /dev/null
+++ b/examples/qml/referenceexamples/coercion/main.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 port of the qml/examples/qml/referenceexamples/coercion example from Qt v6.x"""
+
+from pathlib import Path
+import sys
+
+from PySide6.QtCore import QCoreApplication, QUrl
+from PySide6.QtQml import QQmlComponent, QQmlEngine
+
+from person import Boy, Girl
+from birthdayparty import BirthdayParty
+
+
+app = QCoreApplication(sys.argv)
+qml_file = Path(__file__).parent / "example.qml"
+url = QUrl.fromLocalFile(qml_file)
+engine = QQmlEngine()
+component = QQmlComponent(engine, url)
+party = component.create()
+if not party:
+ print(component.errors())
+ del engine
+ sys.exit(-1)
+host = party.host
+print(f"{host.name} is having a birthday!")
+if isinstance(host, Boy):
+ print("He is inviting:")
+else:
+ print("She is inviting:")
+for g in range(party.guestCount()):
+ name = party.guest(g).name
+ print(f" {name}")
+del engine
+sys.exit(0)
diff --git a/examples/qml/referenceexamples/coercion/person.py b/examples/qml/referenceexamples/coercion/person.py
new file mode 100644
index 000000000..69056014c
--- /dev/null
+++ b/examples/qml/referenceexamples/coercion/person.py
@@ -0,0 +1,47 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, Property
+from PySide6.QtQml import QmlElement, QmlUncreatable
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.coercion.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+@QmlUncreatable("Person is an abstract base class.")
+class Person(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._name = ''
+ self._shoe_size = 0
+
+ @Property(str)
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, n):
+ self._name = n
+
+ @Property(int)
+ def shoe_size(self):
+ return self._shoe_size
+
+ @shoe_size.setter
+ def shoe_size(self, s):
+ self._shoe_size = s
+
+
+@QmlElement
+class Boy(Person):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+
+@QmlElement
+class Girl(Person):
+ def __init__(self, parent=None):
+ super().__init__(parent)
diff --git a/examples/qml/referenceexamples/default/birthdayparty.py b/examples/qml/referenceexamples/default/birthdayparty.py
new file mode 100644
index 000000000..3c13ca6cf
--- /dev/null
+++ b/examples/qml/referenceexamples/default/birthdayparty.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, ClassInfo, Property
+from PySide6.QtQml import QmlElement, ListProperty
+
+from person import Person
+
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.default.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+@ClassInfo(DefaultProperty="guests")
+class BirthdayParty(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._host = None
+ self._guests = []
+
+ @Property(Person)
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, h):
+ self._host = h
+
+ def guest(self, n):
+ return self._guests[n]
+
+ def guestCount(self):
+ return len(self._guests)
+
+ def appendGuest(self, guest):
+ self._guests.append(guest)
+
+ guests = ListProperty(Person, appendGuest)
diff --git a/examples/qml/referenceexamples/default/default.pyproject b/examples/qml/referenceexamples/default/default.pyproject
new file mode 100644
index 000000000..3c01c40c2
--- /dev/null
+++ b/examples/qml/referenceexamples/default/default.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py", "birthdayparty.py", "person.py", "example.qml"]
+}
diff --git a/examples/qml/referenceexamples/default/doc/default.rst b/examples/qml/referenceexamples/default/doc/default.rst
new file mode 100644
index 000000000..1b28519a7
--- /dev/null
+++ b/examples/qml/referenceexamples/default/doc/default.rst
@@ -0,0 +1,30 @@
+.. _qml-default-property-example:
+
+Extending QML - Default Property Example
+========================================
+
+This example builds on the :ref:`qml-adding-types-example`,
+the :ref:`qml-object-and-list-property-types-example` and
+the :ref:`qml-inheritance-and-coercion-example`.
+
+The Default Property Example is a minor modification of the
+:ref:`qml-inheritance-and-coercion-example` that simplifies the
+specification of a BirthdayParty through the use of a default property.
+
+Declaring the BirthdayParty Class
+---------------------------------
+
+The only difference between this example and the last, is the addition of a
+``DefaultProperty`` class info annotation.
+
+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.
+
+Running the Example
+-------------------
+
+The main.py file in the example includes a simple shell application that
+loads and runs the QML snippet shown below.
diff --git a/examples/qml/referenceexamples/default/example.qml b/examples/qml/referenceexamples/default/example.qml
new file mode 100644
index 000000000..435be7860
--- /dev/null
+++ b/examples/qml/referenceexamples/default/example.qml
@@ -0,0 +1,15 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import examples.default.people
+
+BirthdayParty {
+ host: Boy {
+ name: "Bob Jones"
+ shoe_size: 12
+ }
+
+ Boy { name: "Leo Hodges" }
+ Boy { name: "Jack Smith" }
+ Girl { name: "Anne Brown" }
+}
diff --git a/examples/qml/referenceexamples/default/main.py b/examples/qml/referenceexamples/default/main.py
new file mode 100644
index 000000000..a4ce2f08a
--- /dev/null
+++ b/examples/qml/referenceexamples/default/main.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 port of the qml/examples/qml/referenceexamples/default example from Qt v6.x"""
+
+from pathlib import Path
+import sys
+
+from PySide6.QtCore import QCoreApplication, QUrl
+from PySide6.QtQml import QQmlComponent, QQmlEngine
+
+from person import Boy, Girl
+from birthdayparty import BirthdayParty
+
+
+app = QCoreApplication(sys.argv)
+qml_file = Path(__file__).parent / "example.qml"
+url = QUrl.fromLocalFile(qml_file)
+engine = QQmlEngine()
+component = QQmlComponent(engine, url)
+party = component.create()
+if not party:
+ print(component.errors())
+ del engine
+ sys.exit(-1)
+host = party.host
+print(f"{host.name} is having a birthday!")
+if isinstance(host, Boy):
+ print("He is inviting:")
+else:
+ print("She is inviting:")
+for g in range(party.guestCount()):
+ name = party.guest(g).name
+ print(f" {name}")
+del engine
+sys.exit(0)
diff --git a/examples/qml/referenceexamples/default/person.py b/examples/qml/referenceexamples/default/person.py
new file mode 100644
index 000000000..7164bd645
--- /dev/null
+++ b/examples/qml/referenceexamples/default/person.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, Property
+from PySide6.QtQml import QmlAnonymous, QmlElement
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.default.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlAnonymous
+class Person(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._name = ''
+ self._shoe_size = 0
+
+ @Property(str)
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, n):
+ self._name = n
+
+ @Property(int)
+ def shoe_size(self):
+ return self._shoe_size
+
+ @shoe_size.setter
+ def shoe_size(self, s):
+ self._shoe_size = s
+
+
+@QmlElement
+class Boy(Person):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+
+@QmlElement
+class Girl(Person):
+ def __init__(self, parent=None):
+ super().__init__(parent)
diff --git a/examples/qml/referenceexamples/extended/doc/extended.rst b/examples/qml/referenceexamples/extended/doc/extended.rst
new file mode 100644
index 000000000..745960535
--- /dev/null
+++ b/examples/qml/referenceexamples/extended/doc/extended.rst
@@ -0,0 +1,41 @@
+.. _qml-extension-objects-example:
+
+Extending QML - Extension Objects Example
+=========================================
+
+This example builds on the the :ref:`qml-adding-types-example`.
+
+Shows how to use QmlExtended decorator to provide an extension object to a
+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.
+
+.. code-block:: python
+
+ @QmlNamedElement("QLineEdit")
+ @QmlExtended(LineEditExtension)
+ @QmlForeign(QLineEdit)
+ class LineEditForeign(QObject):
+
+
+Note the usage of ``QmlNamedElement()`` instead of ``QmlElement()``.
+``QmlElement()`` 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 ``QLineEdit``
+instead.
+
+The QML engine then instantiates a QLineEdit.
+
+In QML, a property is set on the line edit that only exists in the
+``LineEditExtension`` class:
+
+.. code-block:: javascript
+
+ QLineEdit {
+ left_margin: 20
+ }
+
+The extension type performs calls on the ``QLineEdit`` that otherwise will not
+be accessible to the QML engine.
diff --git a/examples/qml/referenceexamples/extended/example.qml b/examples/qml/referenceexamples/extended/example.qml
new file mode 100644
index 000000000..e4af3bec5
--- /dev/null
+++ b/examples/qml/referenceexamples/extended/example.qml
@@ -0,0 +1,8 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import examples.extend 1.0
+
+QLineEdit {
+ left_margin: 20
+}
diff --git a/examples/qml/referenceexamples/extended/extended.pyproject b/examples/qml/referenceexamples/extended/extended.pyproject
new file mode 100644
index 000000000..127a3a76a
--- /dev/null
+++ b/examples/qml/referenceexamples/extended/extended.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py", "example.qml"]
+}
diff --git a/examples/qml/referenceexamples/extended/main.py b/examples/qml/referenceexamples/extended/main.py
new file mode 100644
index 000000000..6ee386401
--- /dev/null
+++ b/examples/qml/referenceexamples/extended/main.py
@@ -0,0 +1,95 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 port of the qml/examples/qml/referenceexamples/extended example from Qt v6.x"""
+
+from pathlib import Path
+import sys
+
+from PySide6.QtCore import QObject, QUrl, Property
+from PySide6.QtWidgets import QApplication, QLineEdit
+from PySide6.QtQml import (QQmlComponent, QQmlEngine, QmlForeign, QmlExtended,
+ QmlNamedElement)
+
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.extend"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+class LineEditExtension(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._line_edit = parent
+
+ @Property(int)
+ def left_margin(self):
+ return self._line_edit.textMargins().left()
+
+ @left_margin.setter
+ def left_margin(self, m):
+ margins = self._line_edit.textMargins()
+ margins.setLeft(m)
+ self._line_edit.setTextMargins(margins)
+
+ @Property(int)
+ def right_margin(self):
+ return self._line_edit.textMargins().right()
+
+ @right_margin.setter
+ def right_margin(self, m):
+ margins = self._line_edit.textMargins()
+ margins.setRight(m)
+ self._line_edit.setTextMargins(margins)
+
+ @Property(int)
+ def top_margin(self):
+ return self._line_edit.textMargins().top()
+
+ @top_margin.setter
+ def top_margin(self, m):
+ margins = self._line_edit.textMargins()
+ margins.setTop(m)
+ self._line_edit.setTextMargins(margins)
+
+ @Property(int)
+ def bottom_margin(self):
+ return self._line_edit.textMargins().bottom()
+
+ @bottom_margin.setter
+ def bottom_margin(self, m):
+ margins = self._line_edit.textMargins()
+ margins.setBottom(m)
+ self._line_edit.setTextMargins(margins)
+
+
+@QmlNamedElement("QLineEdit")
+@QmlExtended(LineEditExtension)
+@QmlForeign(QLineEdit)
+class LineEditForeign(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+
+if __name__ == '__main__':
+ app = QApplication(sys.argv)
+
+ qml_file = Path(__file__).parent / "example.qml"
+ url = QUrl.fromLocalFile(qml_file)
+ engine = QQmlEngine()
+ component = QQmlComponent(engine, url)
+ widget = component.create()
+ if not widget:
+ print(component.errors())
+ del engine
+ sys.exit(-1)
+
+ widget.show()
+ r = app.exec()
+ # Deleting the engine before it goes out of scope is required to make sure
+ # all child QML instances are destroyed in the correct order.
+ del engine
+ sys.exit(r)
diff --git a/examples/qml/referenceexamples/grouped/birthdayparty.py b/examples/qml/referenceexamples/grouped/birthdayparty.py
new file mode 100644
index 000000000..9f414441e
--- /dev/null
+++ b/examples/qml/referenceexamples/grouped/birthdayparty.py
@@ -0,0 +1,42 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, ClassInfo, Property
+from PySide6.QtQml import QmlElement, ListProperty
+
+from person import Person
+
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.grouped.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+@ClassInfo(DefaultProperty="guests")
+class BirthdayParty(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._host = None
+ self._guests = []
+
+ @Property(Person)
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, h):
+ self._host = h
+
+ def guest(self, n):
+ return self._guests[n]
+
+ def guestCount(self):
+ return len(self._guests)
+
+ def appendGuest(self, guest):
+ self._guests.append(guest)
+
+ guests = ListProperty(Person, appendGuest)
diff --git a/examples/qml/referenceexamples/grouped/doc/grouped.rst b/examples/qml/referenceexamples/grouped/doc/grouped.rst
new file mode 100644
index 000000000..691c1d393
--- /dev/null
+++ b/examples/qml/referenceexamples/grouped/doc/grouped.rst
@@ -0,0 +1,17 @@
+.. _qml-grouped-example:
+
+Extending QML - Grouped Properties Example
+==========================================
+
+Grouped Properties.
+
+This example builds on the the :ref:`qml-default-property-example`,
+the :ref:`qml-inheritance-and-coercion-example`
+the :ref:`qml-object-and-list-property-types-example`
+and the :ref:`qml-adding-types-example`.
+
+Running the Example
+-------------------
+
+The ``main.py`` file in the example includes a simple shell application that
+loads and runs the QML snippet shown below.
diff --git a/examples/qml/referenceexamples/grouped/example.qml b/examples/qml/referenceexamples/grouped/example.qml
new file mode 100644
index 000000000..d0db4f193
--- /dev/null
+++ b/examples/qml/referenceexamples/grouped/example.qml
@@ -0,0 +1,33 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+
+import examples.grouped.people
+
+BirthdayParty {
+ host: Boy {
+ name: "Bob Jones"
+ shoe { size: 12; color: "white"; brand: "Bikey"; price: 90.0 }
+ }
+
+ Boy {
+ name: "Leo Hodges"
+ shoe { size: 10; color: "black"; brand: "Thebok"; price: 59.95 }
+ }
+ Boy { name: "Jack Smith"
+ shoe {
+ size: 8
+ color: "blue"
+ brand: "Luma"
+ price: 19.95
+ }
+ }
+ Girl {
+ name: "Anne Brown"
+ shoe.size: 7
+ shoe.color: "red"
+ shoe.brand: "Job Macobs"
+ shoe.price: 699.99
+ }
+}
diff --git a/examples/qml/referenceexamples/grouped/grouped.pyproject b/examples/qml/referenceexamples/grouped/grouped.pyproject
new file mode 100644
index 000000000..3c01c40c2
--- /dev/null
+++ b/examples/qml/referenceexamples/grouped/grouped.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py", "birthdayparty.py", "person.py", "example.qml"]
+}
diff --git a/examples/qml/referenceexamples/grouped/main.py b/examples/qml/referenceexamples/grouped/main.py
new file mode 100644
index 000000000..f1edb8b94
--- /dev/null
+++ b/examples/qml/referenceexamples/grouped/main.py
@@ -0,0 +1,43 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 port of the qml/examples/qml/referenceexamples/default example from Qt v6.x"""
+
+from pathlib import Path
+import sys
+
+from PySide6.QtCore import QCoreApplication, QUrl
+from PySide6.QtQml import QQmlComponent, QQmlEngine
+
+from person import Boy, Girl
+from birthdayparty import BirthdayParty
+
+
+if __name__ == '__main__':
+ app = QCoreApplication(sys.argv)
+ qml_file = Path(__file__).parent / "example.qml"
+ url = QUrl.fromLocalFile(qml_file)
+ engine = QQmlEngine()
+ component = QQmlComponent(engine, url)
+ party = component.create()
+ if not party:
+ print(component.errors())
+ del engine
+ sys.exit(-1)
+ host = party.host
+ print(f"{host.name} is having a birthday!")
+ if isinstance(host, Boy):
+ print("He is inviting:")
+ else:
+ print("She is inviting:")
+ best_shoe = None
+ for g in range(party.guestCount()):
+ guest = party.guest(g)
+ name = guest.name
+ print(f" {name}")
+ if not best_shoe or best_shoe.shoe.price < guest.shoe.price:
+ best_shoe = guest;
+ if best_shoe:
+ print(f"{best_shoe.name} is wearing the best shoes!");
+ del engine
+ sys.exit(0)
diff --git a/examples/qml/referenceexamples/grouped/person.py b/examples/qml/referenceexamples/grouped/person.py
new file mode 100644
index 000000000..a1edf077e
--- /dev/null
+++ b/examples/qml/referenceexamples/grouped/person.py
@@ -0,0 +1,85 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, Property
+from PySide6.QtGui import QColor
+from PySide6.QtQml import QmlAnonymous, QmlElement
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.grouped.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlAnonymous
+class ShoeDescription(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._brand = ''
+ self._size = 0
+ self._price = 0
+ self._color = QColor()
+
+ @Property(str)
+ def brand(self):
+ return self._brand
+
+ @brand.setter
+ def brand(self, b):
+ self._brand = b
+
+ @Property(int)
+ def size(self):
+ return self._size
+
+ @size.setter
+ def size(self, s):
+ self._size = s
+
+ @Property(float)
+ def price(self):
+ return self._price
+
+ @price.setter
+ def price(self, p):
+ self._price = p
+
+ @Property(QColor)
+ def color(self):
+ return self._color
+
+ @color.setter
+ def color(self, c):
+ self._color = c
+
+
+@QmlAnonymous
+class Person(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._name = ''
+ self._shoe = ShoeDescription()
+
+ @Property(str)
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, n):
+ self._name = n
+
+ @Property(ShoeDescription)
+ def shoe(self):
+ return self._shoe
+
+
+@QmlElement
+class Boy(Person):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+
+@QmlElement
+class Girl(Person):
+ def __init__(self, parent=None):
+ super().__init__(parent)
diff --git a/examples/qml/referenceexamples/methods/birthdayparty.py b/examples/qml/referenceexamples/methods/birthdayparty.py
new file mode 100644
index 000000000..41425a2b1
--- /dev/null
+++ b/examples/qml/referenceexamples/methods/birthdayparty.py
@@ -0,0 +1,47 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, Property, Slot
+from PySide6.QtQml import QmlElement, ListProperty
+
+from person import Person
+
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.methods.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class BirthdayParty(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._host = None
+ self._guests = []
+
+ @Property(Person)
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, h):
+ self._host = h
+
+ def guest(self, n):
+ return self._guests[n]
+
+ def guestCount(self):
+ return len(self._guests)
+
+ def appendGuest(self, guest):
+ self._guests.append(guest)
+
+ @Slot(str)
+ def invite(self, name):
+ guest = Person(self)
+ guest.name = name
+ self.appendGuest(guest)
+
+ guests = ListProperty(Person, appendGuest)
diff --git a/examples/qml/referenceexamples/methods/doc/methods.rst b/examples/qml/referenceexamples/methods/doc/methods.rst
new file mode 100644
index 000000000..bda2ede5a
--- /dev/null
+++ b/examples/qml/referenceexamples/methods/doc/methods.rst
@@ -0,0 +1,15 @@
+.. _qml-methods-example:
+
+Extending QML - Methods Example
+===============================
+
+This example builds on the :ref:`qml-adding-types-example`,
+the :ref:`qml-object-and-list-property-types-example` and
+the :ref:`qml-inheritance-and-coercion-example`.
+
+The Methods Example has an additional method in the ``BirthdayParty`` class:
+``invite()``. ``invite()`` is decorated with ``@Slot`` so that it can be
+called from QML.
+
+In ``example.qml``, the ``invite()`` method is called
+in the ``QtQml.Component.completed()`` signal handler.
diff --git a/examples/qml/referenceexamples/methods/example.qml b/examples/qml/referenceexamples/methods/example.qml
new file mode 100644
index 000000000..c48e952fd
--- /dev/null
+++ b/examples/qml/referenceexamples/methods/example.qml
@@ -0,0 +1,19 @@
+// Copyright (C) 2017 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import examples.methods.people
+
+BirthdayParty {
+ host: Person {
+ name: "Bob Jones"
+ shoe_size: 12
+ }
+ guests: [
+ Person { name: "Leo Hodges" },
+ Person { name: "Jack Smith" },
+ Person { name: "Anne Brown" }
+ ]
+
+ Component.onCompleted: invite("William Green")
+}
diff --git a/examples/qml/referenceexamples/methods/main.py b/examples/qml/referenceexamples/methods/main.py
new file mode 100644
index 000000000..31748ff2b
--- /dev/null
+++ b/examples/qml/referenceexamples/methods/main.py
@@ -0,0 +1,32 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 port of the qml/examples/qml/referenceexamples/methods example from Qt v6.x"""
+
+from pathlib import Path
+import sys
+
+from PySide6.QtCore import QCoreApplication, QUrl
+from PySide6.QtQml import QQmlComponent, QQmlEngine
+
+from person import Person
+from birthdayparty import BirthdayParty
+
+
+app = QCoreApplication(sys.argv)
+qml_file = Path(__file__).parent / "example.qml"
+url = QUrl.fromLocalFile(qml_file)
+engine = QQmlEngine()
+component = QQmlComponent(engine, url)
+party = component.create()
+if not party:
+ print(component.errors())
+ del engine
+ sys.exit(-1)
+host = party.host
+print(f"{host.name} is having a birthday!\nThey are inviting:")
+for g in range(party.guestCount()):
+ name = party.guest(g).name
+ print(f" {name}")
+del engine
+sys.exit(0)
diff --git a/examples/qml/referenceexamples/methods/methods.pyproject b/examples/qml/referenceexamples/methods/methods.pyproject
new file mode 100644
index 000000000..3c01c40c2
--- /dev/null
+++ b/examples/qml/referenceexamples/methods/methods.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py", "birthdayparty.py", "person.py", "example.qml"]
+}
diff --git a/examples/qml/referenceexamples/methods/person.py b/examples/qml/referenceexamples/methods/person.py
new file mode 100644
index 000000000..b5e0bd899
--- /dev/null
+++ b/examples/qml/referenceexamples/methods/person.py
@@ -0,0 +1,34 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, Property
+from PySide6.QtQml import QmlElement
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.methods.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class Person(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._name = ''
+ self._shoe_size = 0
+
+ @Property(str)
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, n):
+ self._name = n
+
+ @Property(int)
+ def shoe_size(self):
+ return self._shoe_size
+
+ @shoe_size.setter
+ def shoe_size(self, s):
+ self._shoe_size = s
diff --git a/examples/qml/referenceexamples/properties/birthdayparty.py b/examples/qml/referenceexamples/properties/birthdayparty.py
new file mode 100644
index 000000000..1a115101b
--- /dev/null
+++ b/examples/qml/referenceexamples/properties/birthdayparty.py
@@ -0,0 +1,41 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, Property
+from PySide6.QtQml import QmlElement, ListProperty
+
+from person import Person
+
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.properties.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class BirthdayParty(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._host = None
+ self._guests = []
+
+ @Property(Person)
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, h):
+ self._host = h
+
+ def guest(self, n):
+ return self._guests[n]
+
+ def guestCount(self):
+ return len(self._guests)
+
+ def appendGuest(self, guest):
+ self._guests.append(guest)
+
+ guests = ListProperty(Person, appendGuest)
diff --git a/examples/qml/referenceexamples/properties/doc/properties.rst b/examples/qml/referenceexamples/properties/doc/properties.rst
new file mode 100644
index 000000000..909434c3c
--- /dev/null
+++ b/examples/qml/referenceexamples/properties/doc/properties.rst
@@ -0,0 +1,89 @@
+.. _qml-object-and-list-property-types-example:
+
+Extending QML - Object and List Property Types Example
+======================================================
+
+Exporting C++ Properties.
+
+This example builds on :ref:`qml-adding-types-example`.
+
+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.
+
+import examples.properties.people
+
+.. code-block:: javascript
+
+ BirthdayParty {
+ host: Person {
+ name: "Bob Jones"
+ shoe_size: 12
+ }
+ guests: [
+ Person { name: "Leo Hodges" },
+ Person { name: "Jack Smith" },
+ Person { name: "Anne Brown" }
+ ]
+ }
+
+Declare the BirthdayParty
+-------------------------
+
+The BirthdayParty class is declared like this:
+
+.. code-block:: python
+
+ from person import Person
+
+
+ # To be used on the @QmlElement decorator
+ # (QML_IMPORT_MINOR_VERSION is optional)
+ QML_IMPORT_NAME = "examples.properties.people"
+ QML_IMPORT_MAJOR_VERSION = 1
+
+
+ @QmlElement
+ class BirthdayParty(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._host = None
+ self._guests = []
+
+ @Property(Person)
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, h):
+ self._host = h
+
+ def guest(self, n):
+ return self._guests[n]
+
+ def guestCount(self):
+ return len(self._guests)
+
+ def appendGuest(self, guest):
+ self._guests.append(guest)
+
+ guests = ListProperty(Person, appendGuest)
+
+The class contains a member to store the celebrant object, and also a
+list member storing the Person instances.
+
+In QML, the type of a list properties - and the guests property is a list of
+people - are all of type ListProperty. ListProperty is simple value
+type that contains a set of functions. QML calls these functions
+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.
+
+Running the Example
+-------------------
+
+The main.py file in the example includes a simple shell application that
+loads and runs the QML snippet shown at the beginning of this page.
diff --git a/examples/qml/referenceexamples/properties/example.qml b/examples/qml/referenceexamples/properties/example.qml
new file mode 100644
index 000000000..1486a0f92
--- /dev/null
+++ b/examples/qml/referenceexamples/properties/example.qml
@@ -0,0 +1,16 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import examples.properties.people
+
+BirthdayParty {
+ host: Person {
+ name: "Bob Jones"
+ shoe_size: 12
+ }
+ guests: [
+ Person { name: "Leo Hodges" },
+ Person { name: "Jack Smith" },
+ Person { name: "Anne Brown" }
+ ]
+}
diff --git a/examples/qml/referenceexamples/properties/main.py b/examples/qml/referenceexamples/properties/main.py
new file mode 100644
index 000000000..a980b25aa
--- /dev/null
+++ b/examples/qml/referenceexamples/properties/main.py
@@ -0,0 +1,34 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 port of the qml/examples/qml/referenceexamples/properties example from Qt v6.x"""
+
+from pathlib import Path
+import sys
+
+from PySide6.QtCore import QCoreApplication, QUrl
+from PySide6.QtQml import QQmlComponent, QQmlEngine
+
+from person import Person
+from birthdayparty import BirthdayParty
+
+
+if __name__ == '__main__':
+ app = QCoreApplication(sys.argv)
+
+ qml_file = Path(__file__).parent / "example.qml"
+ url = QUrl.fromLocalFile(qml_file)
+ engine = QQmlEngine()
+ component = QQmlComponent(engine, url)
+
+ party = component.create()
+ if party:
+ print(f"{party.host} is having a birthday!\nThey are inviting:")
+ for g in range(party.guestCount()):
+ name = party.guest(g).name
+ print(f" {name}")
+ else:
+ print(component.errors())
+
+ del engine
+ sys.exit(0)
diff --git a/examples/qml/referenceexamples/properties/person.py b/examples/qml/referenceexamples/properties/person.py
new file mode 100644
index 000000000..4cc54260a
--- /dev/null
+++ b/examples/qml/referenceexamples/properties/person.py
@@ -0,0 +1,35 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, Property
+from PySide6.QtQml import QmlElement
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.properties.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class Person(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._name = ''
+ self._shoe_size = 0
+
+ @Property(str)
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, n):
+ self._name = n
+
+ @Property(int)
+ def shoe_size(self):
+ return self._shoe_size
+
+ @shoe_size.setter
+ def shoe_size(self, s):
+ self._shoe_size = s
+
diff --git a/examples/qml/referenceexamples/properties/properties.pyproject b/examples/qml/referenceexamples/properties/properties.pyproject
new file mode 100644
index 000000000..0f5958fc3
--- /dev/null
+++ b/examples/qml/referenceexamples/properties/properties.pyproject
@@ -0,0 +1,6 @@
+{
+ "files": ["example.qml",
+ "main.py",
+ "person.py",
+ "birthdayparty.py"]
+}
diff --git a/examples/qml/referenceexamples/valuesource/birthdayparty.py b/examples/qml/referenceexamples/valuesource/birthdayparty.py
new file mode 100644
index 000000000..3bc75e819
--- /dev/null
+++ b/examples/qml/referenceexamples/valuesource/birthdayparty.py
@@ -0,0 +1,76 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QDate, QObject, ClassInfo, Property, QTime, Signal
+from PySide6.QtQml import QmlAnonymous, QmlAttached, QmlElement, ListProperty
+
+from person import Person
+
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.valuesource.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlAnonymous
+class BirthdayPartyAttached(QObject):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._rsvp = QDate()
+
+ @Property(QDate)
+ def rsvp(self):
+ return self._rsvp
+
+ @rsvp.setter
+ def rsvp(self, d):
+ self._rsvp = d
+
+
+@QmlElement
+@ClassInfo(DefaultProperty="guests")
+@QmlAttached(BirthdayPartyAttached)
+class BirthdayParty(QObject):
+
+ partyStarted = Signal(QTime)
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._host = None
+ self._guests = []
+
+ def startParty(self):
+ self.partyStarted.emit(QTime.currentTime())
+
+ @Property(Person)
+ def host(self):
+ return self._host
+
+ @host.setter
+ def host(self, h):
+ self._host = h
+
+ @Property(str)
+ def announcement(self):
+ return ""
+
+ @announcement.setter
+ def announcement(self, a):
+ print(a)
+
+ def guest(self, n):
+ return self._guests[n]
+
+ def guestCount(self):
+ return len(self._guests)
+
+ def appendGuest(self, guest):
+ self._guests.append(guest)
+
+ @staticmethod
+ def qmlAttachedProperties(self, o):
+ return BirthdayPartyAttached(o)
+
+ guests = ListProperty(Person, appendGuest)
diff --git a/examples/qml/referenceexamples/valuesource/doc/valuesource.rst b/examples/qml/referenceexamples/valuesource/doc/valuesource.rst
new file mode 100644
index 000000000..81fbc827f
--- /dev/null
+++ b/examples/qml/referenceexamples/valuesource/doc/valuesource.rst
@@ -0,0 +1,20 @@
+.. _qml-valuesource-example:
+
+Extending QML - Value Source Example
+====================================
+
+This example builds on the :ref:`qml-adding-types-example`,
+the :ref:`qml-attached-properties-example`,
+the :ref:`qml-default-property-example`,
+the :ref:`qml-inheritance-and-coercion-example` and
+the :ref:`qml-object-and-list-property-types-example`.
+
+It demonstrates implementing a
+`property value source <https://doc.qt.io/qt-6/qtqml-cppintegration-definetypes.html#property-value-sources>`_
+in Python.
+
+Running the Example
+-------------------
+
+The main.py file in the example includes a simple shell application that
+loads and runs the QML snippet shown below.
diff --git a/examples/qml/referenceexamples/valuesource/example.qml b/examples/qml/referenceexamples/valuesource/example.qml
new file mode 100644
index 000000000..cb9683f3a
--- /dev/null
+++ b/examples/qml/referenceexamples/valuesource/example.qml
@@ -0,0 +1,27 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import examples.valuesource.people
+
+BirthdayParty {
+ HappyBirthdaySong on announcement { name: "Bob Jones" }
+
+ onPartyStarted: (time) => { console.log("This party started rockin' at " + time); }
+
+ host: Boy {
+ name: "Bob Jones"
+ shoe_size: 12
+ }
+
+ Boy {
+ name: "Leo Hodges"
+ BirthdayParty.rsvp: "2009-07-06"
+ }
+ Boy {
+ name: "Jack Smith"
+ }
+ Girl {
+ name: "Anne Brown"
+ BirthdayParty.rsvp: "2009-07-01"
+ }
+}
diff --git a/examples/qml/referenceexamples/valuesource/happybirthdaysong.py b/examples/qml/referenceexamples/valuesource/happybirthdaysong.py
new file mode 100644
index 000000000..cffddd39e
--- /dev/null
+++ b/examples/qml/referenceexamples/valuesource/happybirthdaysong.py
@@ -0,0 +1,47 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, QTimer, Property, Slot
+from PySide6.QtQml import QmlElement, QPyQmlPropertyValueSource
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.valuesource.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlElement
+class HappyBirthdaySong(QPyQmlPropertyValueSource):
+
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+ self.m_target = None
+ self.m_name = ""
+ self.m_line = -1
+ self.m_lyrics = []
+
+ self.m_timer = QTimer(self)
+ self.m_timer.timeout.connect(self.advance)
+ self.m_timer.start(1000)
+
+ def setTarget(self, property):
+ self.m_target = property
+
+ @Property(str)
+ def name(self):
+ return self.m_name
+
+ @name.setter
+ def name(self, n):
+ self.m_name = n
+ self.m_lyrics = ["Happy birthday to you,",
+ "Happy birthday to you,",
+ f"Happy birthday dear {self.m_name},",
+ "Happy birthday to you!",
+ ""]
+
+ @Slot()
+ def advance(self):
+ self.m_line = (self.m_line + 1) % len(self.m_lyrics)
+ self.m_target.write(self.m_lyrics[self.m_line])
diff --git a/examples/qml/referenceexamples/valuesource/main.py b/examples/qml/referenceexamples/valuesource/main.py
new file mode 100644
index 000000000..c3ded4be9
--- /dev/null
+++ b/examples/qml/referenceexamples/valuesource/main.py
@@ -0,0 +1,51 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 port of the qml/examples/qml/referenceexamples/valuesource example from Qt v6.x"""
+
+from pathlib import Path
+import sys
+
+from PySide6.QtCore import QCoreApplication, QUrl
+from PySide6.QtQml import QQmlComponent, QQmlEngine, qmlAttachedPropertiesObject
+
+from person import Boy, Girl
+from birthdayparty import BirthdayParty
+from happybirthdaysong import HappyBirthdaySong
+
+
+app = QCoreApplication(sys.argv)
+qml_file = Path(__file__).parent / "example.qml"
+url = QUrl.fromLocalFile(qml_file)
+engine = QQmlEngine()
+component = QQmlComponent(engine, url)
+party = component.create()
+if not party:
+ print(component.errors())
+ del engine
+ sys.exit(-1)
+host = party.host
+print(f"{host.name} is having a birthday!")
+if isinstance(host, Boy):
+ print("He is inviting:")
+else:
+ print("She is inviting:")
+for g in range(party.guestCount()):
+ guest = party.guest(g)
+ name = guest.name
+
+ rsvp_date = None
+ attached = qmlAttachedPropertiesObject(BirthdayParty, guest, False)
+ if attached:
+ rsvp_date = attached.rsvp.toString()
+ if rsvp_date:
+ print(f" {name} RSVP date: {rsvp_date}")
+ else:
+ print(f" {name} RSVP date: Hasn't RSVP'd")
+
+party.startParty()
+
+r = app.exec()
+
+del engine
+sys.exit(r)
diff --git a/examples/qml/referenceexamples/valuesource/person.py b/examples/qml/referenceexamples/valuesource/person.py
new file mode 100644
index 000000000..5cd04e38a
--- /dev/null
+++ b/examples/qml/referenceexamples/valuesource/person.py
@@ -0,0 +1,46 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtCore import QObject, Property
+from PySide6.QtQml import QmlAnonymous, QmlElement
+
+# To be used on the @QmlElement decorator
+# (QML_IMPORT_MINOR_VERSION is optional)
+QML_IMPORT_NAME = "examples.valuesource.people"
+QML_IMPORT_MAJOR_VERSION = 1
+
+
+@QmlAnonymous
+class Person(QObject):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+ self._name = ''
+ self._shoe_size = 0
+
+ @Property(str)
+ def name(self):
+ return self._name
+
+ @name.setter
+ def name(self, n):
+ self._name = n
+
+ @Property(int)
+ def shoe_size(self):
+ return self._shoe_size
+
+ @shoe_size.setter
+ def shoe_size(self, s):
+ self._shoe_size = s
+
+
+@QmlElement
+class Boy(Person):
+ def __init__(self, parent=None):
+ super().__init__(parent)
+
+
+@QmlElement
+class Girl(Person):
+ def __init__(self, parent=None):
+ super().__init__(parent)
diff --git a/examples/qml/referenceexamples/valuesource/valuesource.pyproject b/examples/qml/referenceexamples/valuesource/valuesource.pyproject
new file mode 100644
index 000000000..a782d5c8a
--- /dev/null
+++ b/examples/qml/referenceexamples/valuesource/valuesource.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["main.py", "birthdayparty.py", "happybirthdaysong.py", "person.py", "example.qml"]
+}