diff options
Diffstat (limited to 'examples/widgets/painting/plot')
-rw-r--r-- | examples/widgets/painting/plot/doc/plot.png | bin | 0 -> 13030 bytes | |||
-rw-r--r-- | examples/widgets/painting/plot/doc/plot.rst | 36 | ||||
-rw-r--r-- | examples/widgets/painting/plot/plot.py | 66 | ||||
-rw-r--r-- | examples/widgets/painting/plot/plot.pyproject | 3 |
4 files changed, 105 insertions, 0 deletions
diff --git a/examples/widgets/painting/plot/doc/plot.png b/examples/widgets/painting/plot/doc/plot.png Binary files differnew file mode 100644 index 000000000..e5031e351 --- /dev/null +++ b/examples/widgets/painting/plot/doc/plot.png diff --git a/examples/widgets/painting/plot/doc/plot.rst b/examples/widgets/painting/plot/doc/plot.rst new file mode 100644 index 000000000..a63eaed87 --- /dev/null +++ b/examples/widgets/painting/plot/doc/plot.rst @@ -0,0 +1,36 @@ +Plot Example +============ + +The Plot example shows how to display a graph from data using an +`opaque container <https://doc.qt.io/qtforpython-6/shiboken6/typesystem_containers.html>`_. + +It draws an sine graph using ``QPainter.drawPolyline()`` from a list of points. +The list of points is continuously updated, as is the case for a example for a +graph of an oscilloscope or medical patient monitor. +In this case, it makes sense from a performance point of view to avoid the +conversion of a Python list of data to a C++ list (``QList<QPoint>``) +for each call to the plot function ``QPainter.drawPolyline()``. +This is where opaque containers come into play. + +Instead of Python list of points, a ``QPointList`` is instantiated to store +the data. ``QPointList`` is an opaque container wrapping a ``QList<QPoint>``. +It can be passed to ``QPainter.drawPolyline()`` instead of a Python list of +points. + +The type is declared in the entry for the ``QList`` container type in the +type system file of the ``QtCore`` library: + +.. code-block:: xml + + <container-type name="QList" type="list" + opaque-containers="int:QIntList;QPoint:QPointList;QPointF:QPointFList"> + ... + </container-type> + +In the ``shift()`` member function, new data are appended to the list while +old data moving out of the visible window are removed from the front of the +list. + +.. image:: plot.png + :width: 400 + :alt: Plot Screenshot diff --git a/examples/widgets/painting/plot/plot.py b/examples/widgets/painting/plot/plot.py new file mode 100644 index 000000000..fd7ff9937 --- /dev/null +++ b/examples/widgets/painting/plot/plot.py @@ -0,0 +1,66 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + +import math +import sys + +from PySide6.QtWidgets import QWidget, QApplication +from PySide6.QtCore import QPoint, QRect, QTimer, Qt +from PySide6.QtGui import QPainter, QPointList + + +WIDTH = 680 +HEIGHT = 480 + + +class PlotWidget(QWidget): + """Illustrates the use of opaque containers. QPointList + wraps a C++ QList<QPoint> directly, removing the need to convert + a Python list in each call to QPainter.drawPolyline().""" + + def __init__(self, parent=None): + super().__init__(parent) + self._timer = QTimer(self) + self._timer.setInterval(20) + self._timer.timeout.connect(self.shift) + + self._points = QPointList() + self._points.reserve(WIDTH) + self._x = 0 + self._delta_x = 0.05 + self._half_height = HEIGHT / 2 + self._factor = 0.8 * self._half_height + + for i in range(WIDTH): + self._points.append(QPoint(i, self.next_point())) + + self.setFixedSize(WIDTH, HEIGHT) + + self._timer.start() + + def next_point(self): + result = self._half_height - self._factor * math.sin(self._x) + self._x += self._delta_x + return result + + def shift(self): + last_x = self._points[WIDTH - 1].x() + self._points.pop_front() + self._points.append(QPoint(last_x + 1, self.next_point())) + self.update() + + def paintEvent(self, event): + with QPainter(self) as painter: + rect = QRect(QPoint(0, 0), self.size()) + painter.fillRect(rect, Qt.white) + painter.translate(-self._points[0].x(), 0) + painter.drawPolyline(self._points) + + +if __name__ == "__main__": + + app = QApplication(sys.argv) + + w = PlotWidget() + w.show() + sys.exit(app.exec()) diff --git a/examples/widgets/painting/plot/plot.pyproject b/examples/widgets/painting/plot/plot.pyproject new file mode 100644 index 000000000..0ac776c83 --- /dev/null +++ b/examples/widgets/painting/plot/plot.pyproject @@ -0,0 +1,3 @@ +{ + "files": ["plot.py"] +} |