diff options
Diffstat (limited to 'examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes')
4 files changed, 181 insertions, 0 deletions
diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/app.qml b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/app.qml new file mode 100644 index 000000000..a5c5ff9fa --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/app.qml @@ -0,0 +1,22 @@ +// Copyright (C) 2016 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import Charts +import QtQuick + +Item { + width: 300; height: 200 + + PieChart { + id: chart + anchors.centerIn: parent + width: 100; height: 100 + + pieSlice: PieSlice { + anchors.fill: parent + color: "red" + } + } + + Component.onCompleted: console.log("The pie is colored " + chart.pieSlice.color) +} diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pyproject b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pyproject new file mode 100644 index 000000000..af1cfefb7 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/chapter4-customPropertyTypes.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["app.qml", "customPropertyTypes.py"] +} diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/customPropertyTypes.py b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/customPropertyTypes.py new file mode 100644 index 000000000..659850f38 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/customPropertyTypes.py @@ -0,0 +1,83 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +"""PySide6 port of the qml/tutorials/extending-qml/chapter4-customPropertyTypes example + from Qt v5.x""" + +import os +from pathlib import Path +import sys + +from PySide6.QtCore import Property, QUrl +from PySide6.QtGui import QGuiApplication, QPen, QPainter, QColor +from PySide6.QtQml import QmlElement +from PySide6.QtQuick import QQuickPaintedItem, QQuickView, QQuickItem + +# To be used on the @QmlElement decorator +# (QML_IMPORT_MINOR_VERSION is optional) +QML_IMPORT_NAME = "Charts" +QML_IMPORT_MAJOR_VERSION = 1 + + +@QmlElement +class PieSlice (QQuickPaintedItem): + + def __init__(self, parent=None): + QQuickPaintedItem.__init__(self, parent) + self._color = QColor() + + @Property(QColor, final=True) + def color(self): + return self._color + + @color.setter + def color(self, value): + self._color = value + + def paint(self, painter): + pen = QPen(self._color, 2) + painter.setPen(pen) + painter.setRenderHints(QPainter.Antialiasing, True) + painter.drawPie(self.boundingRect().adjusted(1, 1, -1, -1), 90 * 16, 290 * 16) + + +@QmlElement +class PieChart (QQuickItem): + def __init__(self, parent=None): + QQuickItem.__init__(self, parent) + self._name = None + self._pieSlice = None + + @Property(str, final=True) + def name(self): + return self._name + + @name.setter + def name(self, value): + self._name = value + + @Property(PieSlice, final=True) + def pieSlice(self): + return self._pieSlice + + @pieSlice.setter + def pieSlice(self, value): + self._pieSlice = value + self._pieSlice.setParentItem(self) + + +if __name__ == '__main__': + app = QGuiApplication(sys.argv) + + view = QQuickView() + view.setResizeMode(QQuickView.SizeRootObjectToView) + qml_file = os.fspath(Path(__file__).resolve().parent / 'app.qml') + view.setSource(QUrl.fromLocalFile(qml_file)) + if view.status() == QQuickView.Error: + sys.exit(-1) + view.show() + res = app.exec() + # Deleting the view before it goes out of scope is required to make sure all child QML instances + # are destroyed in the correct order. + del view + sys.exit(res) diff --git a/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/doc/chapter4-customPropertyTypes.rst b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/doc/chapter4-customPropertyTypes.rst new file mode 100644 index 000000000..f7c3efb11 --- /dev/null +++ b/examples/qml/tutorials/extending-qml/chapter4-customPropertyTypes/doc/chapter4-customPropertyTypes.rst @@ -0,0 +1,73 @@ +.. _qml-chapter4-custompropertytypes: + +Extending QML - Using Custom Property Types +=========================================== + +This is the fourth of a series of 6 examples forming a tutorial about extending +QML with Python. + +The ``PieChart`` type currently has a string-type property and a color-type property. +It could have many other types of properties. For example, it could have an +int-type property to store an identifier for each chart: + +.. code-block:: python + + class PieChart(QQuickPaintedItem): + chartIdChanged = Signal() + + @Property(int, notify=chartIdChanged) + def chartId(self): + pass + + @chartId.setter + def setChartId(self, chartId): + pass + +.. code-block:: javascript + + // QML + PieChart { + ... + chartId: 100 + } + +Aside from ``int``, we could use various other property types. Many of the Qt +data types such as ``QColor``, ``QSize`` and ``QRect`` are automatically +supported from QML. + +If we want to create a property whose type is not supported by QML by default, +we need to register the type with the QML engine. + +For example, let's replace the use of the ``property`` with a type called +``PieSlice`` that has a ``color`` property. Instead of assigning a color, +we assign an ``PieSlice`` value which itself contains a ``color``: + +.. literalinclude:: app.qml + :lineno-start: 4 + :lines: 4-22 + +Like ``PieChart``, this new ``PieSlice`` type inherits from +``QQuickPaintedItem``, is exposed via the ``QmlElement`` decorator and declares +its properties with the ``Property`` decorator: + +.. literalinclude:: customPropertyTypes.py + :lineno-start: 21 + :lines: 21-40 + +To use it in ``PieChart``, we modify the ``color`` property declaration +and associated method signatures: + +.. literalinclude:: customPropertyTypes.py + :lineno-start: 58 + :lines: 58-65 + +There is one thing to be aware of when implementing ``setPieSlice()``. The +``PieSlice`` is a visual item, so it must be set as a child of the ``PieChart`` +using ``QQuickItem.setParentItem()`` so that the ``PieChart`` knows to paint +this child item when its contents are drawn. + +As with ``PieChart``, we add the ``Charts`` type namespace, version 1.0: + +.. literalinclude:: customPropertyTypes.py + :lineno-start: 15 + :lines: 15-18 |