aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKeith Kyzivat <keith.kyzivat@qt.io>2022-08-02 15:57:17 -0400
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-11-08 14:20:31 +0000
commit8d305aa53c4b00ae51bb000512d3524eb213568f (patch)
tree29b6bd31b598d3db8196421cf931dec2844f4fab
parentfcaeced686b5f387b668b622e0b9f3cdb89b29bf (diff)
PySide6-examples: Charts lightMarker and selection
Provide a python implementation of the pointselectionandmarkers Charts example. Task-number: PYSIDE-841 Change-Id: I9a5295cb89f9e1a400e21f6dbd90d1c8e2827e31 Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io> (cherry picked from commit 1a8db65a6efc8d8d2404f11c7b66baf7bf722ddb) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--examples/charts/pointselectionandmarkers/doc/pointselectionandmarkers.pngbin0 -> 47669 bytes
-rw-r--r--examples/charts/pointselectionandmarkers/doc/pointselectionandmarkers.rst72
-rw-r--r--examples/charts/pointselectionandmarkers/images/blue_triangle.pngbin0 -> 2220 bytes
-rw-r--r--examples/charts/pointselectionandmarkers/images/green_triangle.pngbin0 -> 1389 bytes
-rw-r--r--examples/charts/pointselectionandmarkers/markers.qrc6
-rw-r--r--examples/charts/pointselectionandmarkers/pointselectionandmarkers.py127
-rw-r--r--examples/charts/pointselectionandmarkers/pointselectionandmarkers.pyproject3
-rw-r--r--examples/charts/pointselectionandmarkers/rc_markers.py275
-rw-r--r--examples/charts/pointselectionandmarkers/utilities.py67
9 files changed, 550 insertions, 0 deletions
diff --git a/examples/charts/pointselectionandmarkers/doc/pointselectionandmarkers.png b/examples/charts/pointselectionandmarkers/doc/pointselectionandmarkers.png
new file mode 100644
index 000000000..209bc3b0d
--- /dev/null
+++ b/examples/charts/pointselectionandmarkers/doc/pointselectionandmarkers.png
Binary files differ
diff --git a/examples/charts/pointselectionandmarkers/doc/pointselectionandmarkers.rst b/examples/charts/pointselectionandmarkers/doc/pointselectionandmarkers.rst
new file mode 100644
index 000000000..cf8b9a264
--- /dev/null
+++ b/examples/charts/pointselectionandmarkers/doc/pointselectionandmarkers.rst
@@ -0,0 +1,72 @@
+.. role:: py(code)
+ :language: python
+
+Light Markers and Points Selection Example
+==========================================
+
+The Light Markers and Points Selection example shows how to use light markers
+and point selections in a series.
+
+.. image:: pointselectionandmarkers.png
+ :width: 90%
+ :align: center
+ :alt: QChart with Light Markers shown
+
+Creating the chart and its elements
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We start by creating a series, filling it with the data, and enabling the light marker and point selection features.
+It is important not to set points visibility to :py:`True`, because light markers functionality is an independent feature and setting both would result in undesired behavior.
+
+.. literalinclude:: ../../../../examples/charts/pointselectionandmarkers/pointselectionandmarkers.py
+ :linenos:
+ :lineno-start: 20
+ :lines: 20-42
+ :emphasize-lines: 2-12
+
+Then we create the :py:`QChart`, the :py:`QChartview` and the control widget with its layout to arrange customization elements.
+
+.. literalinclude:: ../../../../examples/charts/pointselectionandmarkers/pointselectionandmarkers.py
+ :lineno-start: 44
+ :lines: 44-53
+ :emphasize-lines: 1,6,9
+
+Creating UI for configuring the chart
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The next step is where we create user interface elements that allow customizing the chart, including setting light marker and selection marker images.
+
+.. literalinclude:: ../../../../examples/charts/pointselectionandmarkers/pointselectionandmarkers.py
+ :linenos:
+ :lineno-start: 54
+ :lines: 54-57
+
+We create the label for the marker selection combobox and fill the combobox with the items. We then provide functionality to the combobox, allowing the user's selection to set the desired light marker image. As light markers are enabled and disabled by setting a valid QImage or setting an empty :py:`QImage()`, we need to make sure that if the user does not wish unselected points to be displayed, we do not actually set the light marker image.
+If checking isn't performed, a new :py:`QImage` will be set as the light marker and unselected points will be visible even though it has been switched off.
+
+.. literalinclude:: ../../../../examples/charts/pointselectionandmarkers/pointselectionandmarkers.py
+ :linenos:
+ :lineno-start: 59
+ :lines: 59-67
+ :emphasize-lines: 1-3
+
+Almost the same procedure applies to the selected point light marker and line color. The only difference is that there is no need to check the visibility of unselected points as it doesn't affect the functionality.
+
+.. literalinclude:: ../../../../examples/charts/pointselectionandmarkers/pointselectionandmarkers.py
+ :linenos:
+ :lineno-start: 70
+ :lines: 70-85
+
+A small difference comes with changing visibility of unselected points. As it was mentioned before, making light markers invisible is achieved by setting the light marker to an empty :py:`QImage()`. That is why, depending on checkbox state, selected point light marker is set to an empty :py:`QImage` or to the light marker extracted from the current index of the corresponding combobox.
+
+.. literalinclude:: ../../../../examples/charts/pointselectionandmarkers/pointselectionandmarkers.py
+ :linenos:
+ :lineno-start: 88
+ :lines: 88-97
+ :emphasize-lines: 5-6
+
+The final part is to lay out the widgets within the main widget and set the main window size.
+
+Usage
+-----
+To use this example, change any of the comboboxes and checkboxes controlling the markers, line color, and unselected point visibility on the right. Then try clicking on points in the chart to select or deselect them.
diff --git a/examples/charts/pointselectionandmarkers/images/blue_triangle.png b/examples/charts/pointselectionandmarkers/images/blue_triangle.png
new file mode 100644
index 000000000..7790453c8
--- /dev/null
+++ b/examples/charts/pointselectionandmarkers/images/blue_triangle.png
Binary files differ
diff --git a/examples/charts/pointselectionandmarkers/images/green_triangle.png b/examples/charts/pointselectionandmarkers/images/green_triangle.png
new file mode 100644
index 000000000..29ae043f2
--- /dev/null
+++ b/examples/charts/pointselectionandmarkers/images/green_triangle.png
Binary files differ
diff --git a/examples/charts/pointselectionandmarkers/markers.qrc b/examples/charts/pointselectionandmarkers/markers.qrc
new file mode 100644
index 000000000..eb1e56d19
--- /dev/null
+++ b/examples/charts/pointselectionandmarkers/markers.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>images/blue_triangle.png</file>
+ <file>images/green_triangle.png</file>
+ </qresource>
+</RCC>
diff --git a/examples/charts/pointselectionandmarkers/pointselectionandmarkers.py b/examples/charts/pointselectionandmarkers/pointselectionandmarkers.py
new file mode 100644
index 000000000..4f9540d42
--- /dev/null
+++ b/examples/charts/pointselectionandmarkers/pointselectionandmarkers.py
@@ -0,0 +1,127 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 port of the Light Markers Points Selection example from Qt v6.2"""
+import sys
+
+from PySide6.QtCore import Slot, QPointF, Qt
+from PySide6.QtCharts import QChart, QChartView, QSplineSeries
+from PySide6.QtGui import QPainter, QImage
+from PySide6.QtWidgets import QApplication, QMainWindow, QWidget, QGridLayout, QComboBox, QCheckBox, QLabel, QHBoxLayout
+
+import utilities as Utilities
+
+if __name__ == "__main__":
+
+ a = QApplication(sys.argv)
+ window = QMainWindow()
+ window.setWindowTitle("Light Markers and Points Selection")
+
+ marker_size = 20.
+ series = QSplineSeries()
+ series.append([QPointF(0, 0),
+ QPointF(0.5, 2.27),
+ QPointF(1.5, 2.2),
+ QPointF(3.3, 1.7),
+ QPointF(4.23, 3.1),
+ QPointF(5.3, 2.3),
+ QPointF(6.47, 4.1)])
+ series.setMarkerSize(marker_size)
+ series.setLightMarker(Utilities.default_light_marker(marker_size))
+ series.setSelectedLightMarker(Utilities.default_selected_light_marker(marker_size))
+
+ @Slot(QPointF)
+ def toggle_selection(point):
+ try:
+ index = series.points().index(point)
+ if index != -1:
+ series.toggleSelection([index])
+ except ValueError:
+ pass
+
+ series.clicked.connect(toggle_selection)
+
+ chart = QChart()
+ chart.addSeries(series)
+ chart.createDefaultAxes()
+ chart.legend().setVisible(False)
+
+ chart_view = QChartView(chart)
+ chart_view.setRenderHint(QPainter.Antialiasing)
+
+ control_widget = QWidget(window)
+ control_layout = QGridLayout(control_widget)
+ char_point_combobox = QComboBox()
+ char_point_selected_combobox = QComboBox()
+ line_color_combobox = QComboBox()
+ show_unselected_points_checkbox = QCheckBox()
+
+ @Slot(int)
+ def set_light_marker(index):
+ if show_unselected_points_checkbox.isChecked():
+ series.setLightMarker(Utilities.get_point_representation(
+ Utilities.point_type(index), marker_size))
+
+ char_point = QLabel("Char point: ")
+ char_point_combobox.addItems(["Red rectangle", "Green triangle", "Orange circle"])
+ char_point_combobox.currentIndexChanged.connect(set_light_marker)
+
+
+ @Slot(int)
+ def set_selected_light_marker(index):
+ series.setSelectedLightMarker(Utilities.get_selected_point_representation(Utilities.selected_point_type(index), marker_size))
+
+ char_point_selected = QLabel("Char point selected: ")
+ char_point_selected_combobox.addItems(["Blue triangle", "Yellow rectangle", "Lavender circle"])
+ char_point_selected_combobox.currentIndexChanged.connect(set_selected_light_marker)
+
+
+ @Slot(int)
+ def set_line_color(index):
+ series.setColor(Utilities.make_line_color(Utilities.line_color(index)))
+
+ line_color_label = QLabel("Line color: ")
+ line_color_combobox.addItems(["Blue", "Black", "Mint"])
+ line_color_combobox.currentIndexChanged.connect(set_line_color)
+
+
+ @Slot(int)
+ def display_unselected_points(checkbox_state):
+ if checkbox_state:
+ series.setLightMarker(Utilities.get_point_representation(Utilities.point_type(char_point_combobox.currentIndex()), marker_size))
+ else:
+ series.setLightMarker(QImage())
+
+ show_unselected_points_label = QLabel("Display unselected points: ")
+ show_unselected_points_checkbox.setChecked(True)
+ show_unselected_points_checkbox.stateChanged.connect(display_unselected_points)
+
+
+ control_label = QLabel("Marker and Selection Controls")
+ control_label.setAlignment(Qt.AlignHCenter)
+ control_label_font = control_label.font()
+ control_label_font.setBold(True)
+ control_label.setFont(control_label_font)
+ control_layout.addWidget(control_label, 0, 0, 1, 2)
+ control_layout.addWidget(char_point, 1, 0)
+ control_layout.addWidget(char_point_combobox, 1, 1)
+
+ control_layout.addWidget(char_point_selected, 2, 0)
+ control_layout.addWidget(char_point_selected_combobox, 2, 1)
+
+ control_layout.addWidget(line_color_label, 3, 0)
+ control_layout.addWidget(line_color_combobox, 3, 1)
+
+ control_layout.addWidget(show_unselected_points_label, 4, 0)
+ control_layout.addWidget(show_unselected_points_checkbox, 4, 1, 1, 2)
+ control_layout.setRowStretch(5, 1)
+
+ main_widget = QWidget(window)
+ main_layout = QHBoxLayout(main_widget)
+ main_layout.addWidget(chart_view)
+ main_layout.addWidget(control_widget)
+
+ window.setCentralWidget(main_widget)
+ window.resize(1080, 720)
+ window.show()
+ sys.exit(a.exec())
diff --git a/examples/charts/pointselectionandmarkers/pointselectionandmarkers.pyproject b/examples/charts/pointselectionandmarkers/pointselectionandmarkers.pyproject
new file mode 100644
index 000000000..499a3bd3c
--- /dev/null
+++ b/examples/charts/pointselectionandmarkers/pointselectionandmarkers.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["pointselectionandmarkers.py", "utilities.py", "markers.qrc", "rc_markers.py"]
+}
diff --git a/examples/charts/pointselectionandmarkers/rc_markers.py b/examples/charts/pointselectionandmarkers/rc_markers.py
new file mode 100644
index 000000000..f5a9cd42b
--- /dev/null
+++ b/examples/charts/pointselectionandmarkers/rc_markers.py
@@ -0,0 +1,275 @@
+# Resource object code (Python 3)
+# Created by: object code
+# Created by: The Resource Compiler for Qt version 6.3.1
+# WARNING! All changes made in this file will be lost!
+
+from PySide6 import QtCore
+
+qt_resource_data = b"\
+\x00\x00\x05m\
+\x89\
+PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
+\x00\x02\x00\x00\x00\x01\xf6\x02\x03\x00\x00\x00{5\xdc\xf0\
+\x00\x00\x00\x09PLTE\x00\x00\x00\x98\xbag\x98\xba\
+g\xb0,\xf9`\x00\x00\x00\x02tRNS\x00\x93\x1f\
+\x95\x0f\xc6\x00\x00\x05\x11IDATx\xda\xdc\xd31\
+\x95\xc4@\x0c\x04\xd1U\x22\x10Bc<Bc\x10N\
+\x5c(\x0fC\xfb\xde\x8c\xe5\xeeX\xc1\x0fT\xbf\x7f.\
+~//\x8f\xdf\xbb\xab\xf3\xf7\xee\xfa\xfa\xbd\xba\xe0\x96\
+\xee\xfd\x00\x09\xd2\x17\xfa\x01\x0a\xa4\x0c\xfc\x00\x0dR\x87\
+v\x80\x00\xa9C?@\x82\xd4\xa1\x1f\xa0@\xea\xd0\x0f\
+\xd0 uh\x07\x08\x90:\xf4\x03$H\x1d\xfa\x01\x0a\
+\xa4\x0e\xfd\x00\x0dR\x87v\x80\x00\xa9C?@\x82\xd4\
+\xa1\x1f\xa0@\xea\xd0\x0f\xd0 uh\x07\x08\x90:\xf4\
+\x03$H\x1d\xfa\x01\x0a\xa4\x0e\xfd\x00\x0dR\x87v\x80\
+\x00\xa9C?@\x82\xd4\xa1\x1f\xa0@\xea\xd0\x0f\xd0 \
+uh\x07\x08\x90:\xf4\x03$H\x1d\xfa\x01\x0a\xa4\x0e\
+\xfd\x00\x0dR\x87v\x80\x00\xa9C?@\x82\xd4\xa1\x1f\
+\xa0@\xea\xd0\x0f\xd0 uh\x07\x08\x90:\xf4\x03$\
+H\x1d\xfa\x01\x0a\xa4\x0e\xfd\x00\x0dR\x87v\x80\x00\xa9\
+C?@\x82\xd4\xa1\x1f\xa0@\xea\xd0\x0f\xd0\xf0n\x87\
+\xcd\xbb\x19\x04#\x01\x1b3\xc8\xa1\x80}\x19\xd4P\xc0\
+\xbe\x0e{(`[\x87\xc1P\xc0\xb6\x0es,`W\
+\x875\x16\xb0\xab\xc3\x1e\x0b\xd8\xd4a0\x16\xb0\xa9\xc3\
+\x1c\x0c\xd8\xd3a\x0d\x06\xec\xe9\xb0\x07\x03\xb6t\x18\x0c\
+\x06l\xe90G\x03vtX\xa3\x01;:\xec\xd1\x80\
+\x0d\x1d\x06\xa3\x01\x1b:\xcc\xe1\x80\xf5\x1d\xd6p\xc0\xfa\
+\x0e{8`y\x87\xc1p\xc0\xf2\x0es<`u\x87\
+5\x1e\xb0\xba\xc3\x1e\x0fX\xdca0\x1e\xb0\xb8\xc3\xfc\
+\x00`m\x87\xf5\x01\xc0\xda\x0e\xfb\x03\x80\xa5\x1d\x06\x1f\
+\x00,\xed0?\x01X\xd9a}\x02\xb0\xb2\xc3\xfe\x04\
+`a\x87\xc1'\x00\x0b;\xcc\x8f\x00\xd6uXo\x03\
+\x1a\xa4\x0e\xed\x00\x01R\x87~\x80\x04\xa9C?@\x81\
+\xd4\xa1\x1f\xa0A\xea\xd0\x0e\x10 u\xe8\x07H\x90:\
+\xf4\x03\x14H\x1d\xfa\x01\x1a\xa4\x0e\xed\x00\x01R\x87~\
+\x80\x04\xa9C?@\x81\xd4\xa1\x1f\xa0A\xea\xd0\x0e\x10\
+(\xbb\x0d\x01\x89\xb4\xc3\x0fPH;\xfd\x00\x8d\xb4\xcb\
+\x0e\x10h\xbb\xed\x00\x89\xb8\xc3\x0dP\x88;\xdd\x00\x8d\
+\xb8\xcb\x0c\x10\xa8\xbb\xcd\x00\x89\xbc\xc3\x0bP\xc8;\xbd\
+\x00\x8d\xbc\xcb\x0a\x10\xe8\xbb\xad\x00\x09\xfa\x0e'@\x81\
+\xbe\xd3\x09\xd0\xa0\xef2\x02\x04Ov\x1b\x01\x92G;\
+|\x00\xc5\xa3\x9d>\x80\xe6\xd1.\x1b@\xf0l\xb7\x0d\
+ y\xb8\xc3\x05P<\xdc\xe9\x02h\x1e\xee2\x01\x04\
+Ow\x9b\x00\x92\xc7;<\x00\xc5\xe3\x9d\x1e\x80\xe6\xf1\
+.\x0b@\xf0|\xb7\x05\xe0\x8f{:(\x82(\x06\x81\
+ Z\xb9 \x22j\xd0\x83\x1aDpaT\xae\x86\xd4\
+\x87,\x93V\xf0.-\xf8\x90\xbe\x00\xd8\xf8\x90\xbf\x00\
+0|(\x1e\x00,|)\x1f\x00\x08>\xa5\xfc\x80\x8d\
+O9?\xc0\xf0\xa9\xa0\x07,|+\xe9\x01\x82\x8f)\
+;`\xe3c\xce\x0e0|,\xc8\x01\x0b_Kr\x80\
+\xe0s\xca\x0d\xd8\xf8\x9cs\x03\x0c\x9f\x0bj\xc0\xc2\xf7\
+\x92\x1a (H\x99\x01\x1b\x0593\xc0PP\x10\x03\
+\x16*Jb\x80\xa0$\xe5\x05l\x94\xe4\xbc\x00CI\
+A\x0bX\xa8)i\x01\x82\xa2\x94\x15\xb0Q\x94\xb3\x02\
+\x0cE\x05)`\xa1\xaa$\x05\x08\xcaRN\xc0FY\
+\xce\x090\x94\x15\x94\x80\x85\xba\x92\x12 (L\x19\x01\
+\x1b\x859#\xc0PX\x10\x02\x16*KB\x80\xa04\
+\xe5\x03l\x94\xe6|\x00CiA\x07X\xa8-\xe9\x00\
+\x82\xe2\x94\x0d\xb0Q\x9c\xb3\x01\x0c\xc5\x05\x19`\xa1\xba\
+$\x03\x08\xcaS.\xc0Fy\xce\x050\x94\x17T\x80\
+\x85\xfa\x92\x0a hH\x99\x00\x1b\x0d9\x13\xc0\xd0P\
+\x10\x01\x16:J\x22\x80\xa0%\xe5\x01l\xb4\xe4<\x00\
+CKA\x03X\xe8)i\x00\x82\xa6\x94\x05\xb0\xd1\x94\
+\xb3\x00\x0cM\x05\x09`\xa1\xab$\x01\x08\xdaR\x0e\xc0\
+F[\xce\x010\xb4\x15\x14\x80\x85\xbe\x92\x02 hL\
+\x19\x00\x1b\x8d9\x03\xc0\xd0X\x10\x00\x16:K\x02\x80\
+\xa05\x9d\x0f\xd8h\xcd\xe7\x03\x0c\xad\xc5x\xc0Bo\
+9\x1e hN\xa7\x036\x9a\xf3\xe9\x00Cs1\x1c\
+\xb0\xd0]\x0e\x07\x08\xda\xd3\xd9\x80\x8d\xf6|6\xc0\xd0\
+^\x8c\x06,\xf4\x97\xa3\x01\x82\x0b\xe9d\xc0\xc6\x85|\
+2\xc0p\xa1\x18\x0cX\xb8Q\x0e\x06\x08\xae\xa4s\x01\
+\x1bW\xf2\xb9\x00\xc3\x95b,`\xe1N9\x16 \xb8\
+\x94N\x05l\x5c\xca\xa7\x02\x0c\x97\x8a\xa1\x80\x85[\xe5\
+P\x80\xe0Z:\x13\xb0q-\x9f\x090\x5c+F\x02\
+\x16\xee\x95#\x01\x82\x8b\xe9D\xc0\xc6\xc5|\x22\xc0p\
+\xb1\x18\x08X\xb8Y\x0e\x04\x08\xae\xa6\xff\x06\xf8\xe1\x85\
+\xef\x01\xe2\xf0\xc2\xf7\x00yx\xe1{\x00\xe8\xe1\x85\xef\
+\x01\xfc\xf0\xc2\xf7\x00qx\xe1{\x80<\xbc\xf0=\x00\
+\xf4\xf0\xc2\xf7\x00~x\xe1{\x808\xbc\xf0=@\x1e\
+^\xf8\x1e\x00zx\xe1{\x00?\xbc\xf0=@\x1c^\
+\xf8\x1e \x0f/|\x0f\x00=\xbc\xf0=\x80\x1f^\xf8\
+\x1e\xe0\xd7=\x1d\x13\x01\x00\xc30\x0c\xa4f\x88\x01\x91\
+%FY\x0c\x9az'\x06\xbf\xfc\xc2\x85>\xc0\xc1\x85\
+>@\x03\x17\xfa\x00\x03\x17\xfa\x00\x0b\x17\xfa\x00\x07\x17\
+\xfa\x00\x0d\x5c\xe8\x03\x0c\x5c\xe8\x03,\x5c\xe8\x03\x1c\x5c\
+\xe8\x034p\xa1\x0f0p\xa1\x0f\xb0p\xa1\x0fpp\
+\xa1\x0f\xd0\xfc]\xd8\xe6\x01\x9f\xda\xf9\x10\xf2\x1c\xc7\xb0\
+\x00\x00\x00\x00IEND\xaeB`\x82\
+\x00\x00\x08\xac\
+\x89\
+PNG\x0d\x0a\x1a\x0a\x00\x00\x00\x0dIHDR\x00\
+\x00\x01\x00\x00\x00\x00\xfb\x08\x03\x00\x00\x00\xb2\x8e\xba:\
+\x00\x00\x00\x8dPLTE\x00\x00\x00i\xba\xf0i\xba\
+\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0\
+i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\
+\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\xba\
+\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0\
+i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\
+\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\xba\
+\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0\
+i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\xba\xf0i\
+\xba\xf0i\xba\xf0\x9c\xb2p\x14\x00\x00\x00.tRN\
+S\x00\x05\xf7\xfb\x19\x13U\x09\xf3\xe2H\x1d\x94z\x0f\
+0\xdf\xc9e\xec\xcd3\x22\xa37\x86\xda\xc0tO\xac\
+\xe5\xb8\x80\xb3k\xe9\x9a\xa7\xc5*\xd4@_\x8e:=\
+\xa4\x0e\xbb\x00\x00\x07\xa0IDATx\xda\xe4\xdd\x07\
+b\xaa@\x10\x80av\x11\x10i\x8a\x82=\xf6\xae{\
+\xff\xe3=\xf2L\x1c\xc0(b\x81e\xe6?\x020\xbb\
+\x9f\x94D)3V\xdbnk.S\xc8\xc6\xc2\xfd\xde\
+\xb3\x5c\x85ll\xef\xf4G\xfa\x96\xee%\xe0\xfa\xc3\xce\
+\xd4\x1e\x1b\x0a\xd5\xc2Y\x93O\xa6\xbe\xa6\xd0\x8ci\xfb\
+U[\x88\xc1,Th\xa6\xf5\x16s.D}\xb5\xd7\
+h\xae\x02\x96\xdf\xdd\xa9B\xf0\xe9\xe2Ds\x08\x02{\
+P\xff>\x00\xbb\xaeOr\x08\x8c\xf1\x9c\x8b(\xb5\xdd\
+9\x06\x0a\xb9\x98\xeb-Z\xe2\x5c}\xde\xa0\xb7\x08\xb0\
+\xadn\x0f\xc4O\x1d\xdf\x22g\x01\xa3\xd1\x1f\xb6\xc5O\
+M[\x0f\xa9]\x03\xae?\x9dp\xf1S{xlP\
+\xbb\x04\xc2\xd9@\x15\xbfq\x93\x1a\x07\xcf\x08\x84Tj\
+\x1c\xd4z\xfe\x9c\x8bK\xf48\x18\x9e\x11\x08E\x1c\xec\
+Q\x1a\x823\x02/\x91\xe3\xa01\x9er\x91Hm\xb7\
+\x8e=\x85H\xcc\xdd\x8e:\xe2\x12=\x0e\x02\x02\x13u\
+\x16\x16\x91#\x00\x08\xfc\x1f=\x0e\x02\x02\xffG\x8f\x83\
+\x09\x04\x0ar\x1cL!\x90\x1e\x07\xb5 \x81@z\x1c\
+\x04\x04^\xa5\x92\xe0 \xf0*\x95\x02\x07\x01\x81\xd7\
+\xa9K\xf4\x1cL#\xf0\x9a\x83c\xdc\x8b\xc07\x02\x9b\
+\xe2\x12=\x0e\x02\x02od\xdac\xd4\x1c\x8c\x10hr\
+q\x89\x1e\x07\x93\x08$\xc7\xc1\x14\x02\xe9q0\x85\xc0\
+[\x1c<\xa1}k(\xf4Wq\x04\xd2\xe3`\xcf\xde\
+\xd5\x05D\x8e\x83I\x04\xde\xe3\xe0IA\x18 0\xab\
+\xfaT\xc78\x03\x06 0\xab\x9d\xe3!\xfcY\x0c\x08\
+\xccl\xd2\xf5=|\x07@\x03\x04fU\xeftu|\
+\xaf\x8ff 0\xf5\x94dd)\xb8\x02\x04>\xd4\xe4\
+\x88m\x06\x00\x81\x0f\xc5\xd7\xe3\x10\xd7o\xa2\xf0\xb0\xda\
+\x89\x1c\xb5\xfa\xe3\x9a\x82)@\xe0C\xa9\xe6t\xe6)\
+\x88b\x80\xc0\xc7\xe2f\x17\xd1\xb3R@\xe0\xe3\xa9\xc3\
+C\x0d\xcd\x11\x00\x04\xe6h0;\xa19\x02\x11\x02\xa7\
+m\x91\xb3\xc9z\x11`\xd9\x08\x22\x046\xb9\xb8D\x8f\
+\x83\x11\x02\xb9\xc8\x9b\xda\xde \xe1`\x0a\x81\xf48\xa8\
+y\x80\xc0\x5c\xf1\xaf1\x8aw\xa8\x01\x81yk\xcd\x1a\
+\x188\x98D`>\x0e:\x088\xc8t@`\xcex\
+\xb3\xfa\x1cL!\x90\x1e\x07S\x08\xa4\xc7A@\xe0S\
+-+\xcfA\xcd\x9f\xc7\x11\x98\x9f\x83\xab\x8as\xf0\x1b\
+\x81\xaax:^q\x0e\xa6\x10H\x8f\x83\xdf\x08\x8c\x9d\
+\x7fz\x1cL\x22\x90 \x07\x01\x81\xcfW\xe5\xbb\x83I\
+\x04\x92\xe3 \xf0\xb5\xd4ME9\x98B =\x0e\
+\xa6\x10\xf8\x0a\x07\xfdJr0\x85@z\x1c\xdc\xf6\x01\
+\x81/\xc5\x97U\xe4\xa0a5\xba\xb1\x01\xa0\xc7\xc1\xda\
+~4\x8c\x9d\x7fz\x1c\xdc\x8e\xbeb[\x00A\x0e\xee\
+\xd7\xf1O\xe3\xe8q\xd0=\xb4\xc4\x1b\xe3\xe6\xbaR\x1c\
+d\xb5S\x7f \xde\x99\xba\xf1\xab\x84!\xa3\xb7XO\
+\xc4%z\x1c\xd4\xf4U\xa7..\xd1\xe3\xa05j\xb5\
+Uq\x89\x1c\x07\x99g'\x06\x80\x1a\x07\x8dP\xff\xe2\
+\xe2\xedM\xec\xaap\xd0j\xcc6\xaax{je8\
+\xe89\xf3\x18\x02\x09r\xb0\x01\x08|kUyX\xec\
+\x1e:\xe2#\xf1f\x158\x08\x08|\x7f\xbc\x0a\x1c\x04\
+\x04~\xa0A_~\x0eF\x08l%\x11H\x8c\x83W\
+\x08\xa4\xc6\xc14\x02\x89q0\x13\x81\xafs0\x90z\
+\x11\xf8\x0b\x81\xa48\xe8\xfd}'\x90\x0e\x07\x1bk\x93\
+\x8b\xab\xe8p\xf0\x16\x02\x89p\xf0c\x08LsP\xd6\
+\x19\xb8\x87@\x12\x1c\xd4t\xfb&\x02Ip\x10\x10\xf8\
+\xd1\xea\xad\x95\xa4\x9f\xd7\xdfF \x09\x0e\x02\x02?\x9e\
+)%\x07\xef#\x90\x00\x07\x01\x81\x9f\xaf\xe5H\xc8\xc1\
+L\x04\x22\xe7\xa0\xebg \x107\x07\x99\xd6\xebg\x0d\
+\x00j\x0e\xba=\xbf\x00\x04&8\xd8\x93\x8a\x83\x80\xc0\
+\x82jK\xc6Ak\xb4Y\xaa\x22+\xc4\x1c\x04\x04\x16\
+\x14\x9f\x0c%\xe2 \xb0\xb8T\x998X\x14\x02\xd3\
+\x1c\xac\xc9\xb2\x0a\xe4A J\x0e\x02\x02\x8b\xcc\x9c;\
+\x92\xfc\x8f\xb6\x5c\x08\xc4\xc7\xc1\x9c\x08\xc4\xc7\xc1o\x04\
+.E\xb1\x01\x07%\xf8\xbb\x83\x80\xc0\xc2kw\x0f^\
+\xf9\x1b\x81\xe5\x14\x88\xc04\x07m\x098\xe8\xd9%\x0c\
+\x00p0T\xca\xcd\xb0\xf2\x22\x10\x19\x07#\x04\xb6J\
+\x19\x00\xe0`\xb9G (\x1c\x81i\x0e\xee\xcb\xdd\x0a\
+\x1b\xeb'>\x8dC\xc4\xc12\x10\x98\xe6\xe08\xe7\x0c\
+\xa0@ \xc4[\x8b\xf2f\xc0\x0d\xfc\xeeR\x94\x5c3\
+/\x07q P\x0e\x0e>\x8d@,\x1c\xf4\xec\xd2\x07\
+\xa0\x14\x0e\x02\x02\xe7\x5c\x94_\xc4\xc1\x1eS\x0a\x0d\x10\
+(dH\x9d?\xceAL\x08,\x9d\x83\x11\x02e\x98\
+\x80|\x1c\xc4\x84\xc08\x07\xbf\x1e\xe3 2\x04\x96\xca\
+A78\x94\x8f\xc0R8\x08\x08\xdc\x94\x8e\xc0\xbc\x1c\
+D\x87\xc029\xe8\xad$\x1a\x80\xff\x1ct\xb28\x88\
+\x11\x81y8\x88\x13\x81y8\x88\x13\x81P\xa7H\x0e\
+\x8e\xd7\x03\x89\xb6\x80\xe29\xa8\xc9\x83@\xa8~\x97\x83\
+x\x11\xf80\x07\xd1\x22\xb0x\x0e\xd6\xf4\xa3L\x08|\
+\x90\x83x\x11X<\x07\x03\xb9\x10\xf8\x10\x07Q#0\
+\xc9A\xe5\xaf\x90#0\x9b\x83\xd8\x11X$\x07\x99\x8c\
+\x08,\x92\x83\xda\xa2#\xe5\x0eP\x10\x07\x99\x16H\x89\
+\xc0\xc28\xe8z\x92\x22\xf0\x1e\x07I \xb0(\x0eZ\
+\xcep\x22\xf3\x12\xf0'\x07I \xf0\xd3\x1c\x04\x04J\
+~\xfe\xaf\xef\x0e\x92A`\x9c\x83\xfag8\xc8zR\
+#\xf0\x06\x07\xe9 \xf0o\x0e\x12B\xe0\xa79\xc8\xdc\
+\xa0o\x8aj\x04\x1c|3\x02\xdb\xa2\x22\xfdr\x90\x18\
+\x02?\xcb\xc1P~\x04B\xfc\xccAj\x08\xfc$\x07\
+Y%\x10\x08\x16R\xcdU\xef\xdd\x08\x94\xf0iX\x16\
+\x07\x09\x220\xc9A\x82\x08Lr\x90 \x02\xa1\xfa \
+\xe2 A\x04&9H\x11\x81)\x0e\xd2C`\x8a\x83\
+\xf4\x10\x08\xf1\xd6Q\xd7\xe8!\xf0\xfd\x1cd5}Z\
+\xc1\xf3\x1f\xc5\xcd\xd5\x89\x11D`\x8a\x83\x04\x11\xf8^\
+\x0e\xb2q\xb7j\x08\x84\xcc/' \x88\xc0\x14\x07\x09\
+\x220\xc9A\x8a\x08\x8cs0p\xd9+\x08\x1c\xf7\xab\
+\x88\xc0\x04\x07\xb7\x06=\x04&9X\xa3\x87\xc0\x14\x07\
+\x09\x220\xc9A\x8a\x08\x84\xd4i\xc4A\x82\x08|\x89\
+\x83\x80\xc0]\xa5\xb7\x80_\x0e\x8e\x82\xa7\x11(\xeb[\
+\xc199\xa83\x82\x08Lr\x90\x22\x02!\x138\x98\
+\x13\x81\x18& \xaa\xbe\xd6\xb7.=\x04\xbe\xca\xc1`\
+\x85d\x00~8H\x10\x81I\x0e2\x82\x08|\x8a\x83\
+\x80@\x1c{\xe0\x93\x1c4p 0\xc9A\x82\x08\x8c\
+sp\xad\xb3\x1c\x08\xf4\x90 \xf0\x92\x9a\x8b\x83\xeeV\
+\xc7\x82\xc0\x9c\x1c\x04\x04\x0eqM@T\xbd\xabo\x0d\
+z\x08\x84\xf8\xe6q\x0e\xf6d\xff2\xea\x99Ts\xe8\
+l\x1fF\xa0\xc0\x97\xfa\xe8\xddA\x86\x0c\x81)\x0e\x12\
+D \xb4\x8b8\xc8\xe8!\x10\x9a\xcc\x9d\x13\xa3\x87@\
+\x88O\xa6\x07#k\x00\x0ct\x08\x8c\xa5\xee\x9c\x90\x22\
+\x02\xa1\xa5\xbd\xaf\x19\xf4\x10\x08\xf1\xf9\xe2\xa4\xd1C`\
+|\x06\xd6\xbeu\x1f\x81\x98\x07@\x08\xb5>\xb0\xbd\xfb\
+\x08\x1c\x0a\xdc\xd5\xbf\x1a\x06A\x04\xc6\xda,<\x8d \
+\x02\xa1\x81\xado\xd9-\x04\xeah\x11\x08\xb5\x87\xc7=\
+\xbb\x83@\xc4[\xc09\xbe\x1c\x1e\x0c\x82\x08\x8c5p\
+B\x8a\x08Lr\x90\xd1C\xe0\x1d\x0e\x02\x02M\xf4+\
+\xc0\x99\x83]\xdf\xa2\x87\xc0,\x0e2\x0d=\x02!>\
+o\x18\x7f p'\xc8\xf4\xcdA\x82\x08\xfcW\x9e\x1d\
+\xa3\x00\x08\x03A\x14]\x95\x10Q\x12Q,D,\x84\
+46z\xff\xe3i\xaau\xd6\xca63\x97\xf8\x0f\xc6\
+p\x90\x0f\x81\xc0\xc1\xae\xb2\x08l)\x12\xa0\x1c\x8c\xf2\
+\x1a\x0b\x02\x81\x83\x8c\x084\x1c\xe4C pp\xd1\x10\
+\x1ca\xe7@\xa0\xe1`\xd9w\xf0\x0f\x0e2!\x109\
+\xc8\x88@\xdd\x98\x86(\xcf\xfcI\x85\xc0/\x07\x1d\x17\
+\x02\x91\x83>7p\xa3B pp\xca%\xec\xc3z\
+Q\xae\xa9\xe7\xe4\xe4\x06\xc7Z\x00\x1d\x81h\xe2\xc4\x00\
+\x00\x00\x00IEND\xaeB`\x82\
+"
+
+qt_resource_name = b"\
+\x00\x06\
+\x07\x03}\xc3\
+\x00i\
+\x00m\x00a\x00g\x00e\x00s\
+\x00\x12\
+\x0c\xf7v\xe7\
+\x00g\
+\x00r\x00e\x00e\x00n\x00_\x00t\x00r\x00i\x00a\x00n\x00g\x00l\x00e\x00.\x00p\x00n\
+\x00g\
+\x00\x11\
+\x02\xf5Q\x07\
+\x00b\
+\x00l\x00u\x00e\x00_\x00t\x00r\x00i\x00a\x00n\x00g\x00l\x00e\x00.\x00p\x00n\x00g\
+\
+"
+
+qt_resource_struct = b"\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00\x00\x00\x02\x00\x00\x00\x02\x00\x00\x00\x02\
+\x00\x00\x00\x00\x00\x00\x00\x00\
+\x00\x00\x00<\x00\x00\x00\x00\x00\x01\x00\x00\x05q\
+\x00\x00\x01\x82`\x07\x0a\xa2\
+\x00\x00\x00\x12\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
+\x00\x00\x01\x82`\x07!\xf4\
+"
+
+def qInitResources():
+ QtCore.qRegisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+def qCleanupResources():
+ QtCore.qUnregisterResourceData(0x03, qt_resource_struct, qt_resource_name, qt_resource_data)
+
+qInitResources()
diff --git a/examples/charts/pointselectionandmarkers/utilities.py b/examples/charts/pointselectionandmarkers/utilities.py
new file mode 100644
index 000000000..6b96d6e26
--- /dev/null
+++ b/examples/charts/pointselectionandmarkers/utilities.py
@@ -0,0 +1,67 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+from PySide6.QtGui import QImage, QPainter, QColor
+from PySide6.QtCore import Qt
+
+import rc_markers
+
+def rectangle(point_type, image_size):
+ image = QImage(image_size, image_size, QImage.Format_RGB32)
+ painter = QPainter()
+ painter.begin(image)
+ painter.setRenderHint(QPainter.Antialiasing)
+ painter.fillRect(0, 0, image_size, image_size, point_type[2])
+ painter.end()
+ return image
+
+def triangle(point_type, image_size):
+ return QImage(point_type[3]).scaled(image_size, image_size)
+
+def circle(point_type, image_size):
+ image = QImage(image_size, image_size, QImage.Format_ARGB32)
+ image.fill(QColor(0, 0, 0, 0))
+ painter = QPainter()
+ painter.begin(image)
+ painter.setRenderHint(QPainter.Antialiasing)
+ painter.setBrush(point_type[2])
+ pen = painter.pen()
+ pen.setWidth(0)
+ painter.setPen(pen)
+ painter.drawEllipse(0, 0, image_size * 0.9, image_size * 0.9)
+ painter.end()
+ return image
+
+_point_types = [("RedRectangle", rectangle, Qt.red),
+ ("GreenTriangle", triangle, Qt.green, ":/images/green_triangle.png"),
+ ("OrangeCircle", circle, QColor(255, 127, 80))]
+_selected_point_types = [("BlueTriangle", triangle, Qt.blue, ":/images/blue_triangle.png"),
+ ("YellowRectangle", rectangle, Qt.yellow),
+ ("LavenderCircle", circle, QColor(147, 112, 219))]
+_line_colors = [("Blue", QColor(65, 105, 225)), ("Black", Qt.black), ("Mint", QColor(70, 203, 155))]
+
+def point_type(index):
+ return _point_types[index]
+
+def selected_point_type(index):
+ return _selected_point_types[index]
+
+def line_color(index):
+ return _line_colors[index]
+
+
+def default_light_marker(image_size):
+ return rectangle(_point_types[0], image_size)
+
+def default_selected_light_marker(image_size):
+ return triangle(_selected_point_types[0], image_size)
+
+
+def get_point_representation(point_type, image_size):
+ return point_type[1](point_type, image_size)
+
+def get_selected_point_representation(point_type, image_size):
+ return point_type[1](point_type, image_size)
+
+def make_line_color(line_color):
+ return line_color[1]