aboutsummaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
authorKeith Kyzivat <keith.kyzivat@qt.io>2022-11-10 14:27:53 -0500
committerKeith Kyzivat <keith.kyzivat@qt.io>2023-01-19 15:45:48 -0500
commit8111875a7fe11b856bc2c6960d7b196607bc1f0c (patch)
tree48bfec417d93a8cdc114bc83638d32a966770a9b /examples
parent50d3f6cd3ab69d9f5dadb8cc308b3aeaf8c27938 (diff)
PySide6-examples: Charts selected point configuration example
Add an example that shows how to customize individual points on a chart, such as changing the color or providing a a custom label. Task-number: PYSIDE-841 Change-Id: I09b48dd4e77f03355d1bb1207d7666a9fb3801f0 Reviewed-by: Venugopal Shivashankar <Venugopal.Shivashankar@qt.io>
Diffstat (limited to 'examples')
-rw-r--r--examples/charts/pointconfiguration/chartwindow.py157
-rw-r--r--examples/charts/pointconfiguration/doc/pointconfiguration.pngbin0 -> 34991 bytes
-rw-r--r--examples/charts/pointconfiguration/doc/pointconfiguration.rst148
-rw-r--r--examples/charts/pointconfiguration/pointconfiguration.py17
-rw-r--r--examples/charts/pointconfiguration/pointconfiguration.pyproject3
5 files changed, 325 insertions, 0 deletions
diff --git a/examples/charts/pointconfiguration/chartwindow.py b/examples/charts/pointconfiguration/chartwindow.py
new file mode 100644
index 000000000..93acca506
--- /dev/null
+++ b/examples/charts/pointconfiguration/chartwindow.py
@@ -0,0 +1,157 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+"""PySide6 port of the Selected Point Configuration Example from Qt 6.5"""
+from PySide6.QtCore import QObject, QPointF, Slot
+from PySide6.QtGui import QColor, QIcon, QPainter
+from PySide6.QtWidgets import QMainWindow, QLineEdit, QLabel, QComboBox
+from PySide6.QtWidgets import QCheckBox, QWidget, QGridLayout, QHBoxLayout
+from PySide6.QtCharts import QLineSeries, QXYSeries, QChart, QChartView
+
+
+PointConfig = QXYSeries.PointConfiguration
+
+
+class ChartWindow(QMainWindow):
+ def __init__(self, parent:QObject=None ):
+ super().__init__(parent)
+
+ tr=self.tr
+ self.setWindowTitle(tr("Chart"))
+ self._series = QLineSeries(self)
+ self._series.setName(tr("Customized series"))
+ self._series.setPointsVisible(True)
+ self._series.append([QPointF(0, 7), QPointF(2, 4),
+ QPointF(3, 5), QPointF(7, 4), QPointF(10, 5),
+ QPointF(11, 1), QPointF(13, 3), QPointF(17, 6),
+ QPointF(18, 3), QPointF(20, 2)])
+
+ selected_point_index_label = QLabel(tr("Selected Point: "))
+ self._selected_point_index_lineedit = QLineEdit()
+ self._selected_point_index_lineedit.setReadOnly(True)
+ self._selected_point_index_lineedit.setStyleSheet(
+ "background-color: rgba(0, 0, 0, 0); border: 0px")
+
+ color_label = QLabel(tr("Color: "))
+ self._color_combobox = QComboBox()
+ color_strings = ["red", "orange", "yellow", "green", "blue", "indigo", "violet", "black"]
+ tr_color_strings = [tr("red"), tr("orange"), tr("yellow"), tr("green"), tr("blue"),
+ tr("indigo"), tr("violet"), tr("black")]
+ for i, color_str in enumerate(color_strings):
+ self._color_combobox.addItem(QIcon(), tr_color_strings[i], QColor(color_str))
+
+ size_label = QLabel(tr("Size: "))
+ self._size_combobox = QComboBox()
+ for size in [2, 3, 4, 6, 8, 10, 12, 15]:
+ self._size_combobox.addItem(QIcon(), str(size), size)
+
+ label_visibility_label = QLabel(tr("Label Visibility: "))
+ self._label_visibility_checkbox = QCheckBox()
+
+ custom_label_label = QLabel(tr("Custom Label: "))
+ self._custom_label_lineedit = QLineEdit()
+
+ self._series.clicked.connect(self._select_point)
+ self._color_combobox.activated.connect(self._set_color)
+ self._size_combobox.activated.connect(self._set_size)
+ self._label_visibility_checkbox.clicked.connect(self._set_label_visibility)
+ self._custom_label_lineedit.editingFinished.connect(self._set_custom_label)
+
+ self._chart = QChart()
+ self._chart.addSeries(self._series)
+ self._chart.createDefaultAxes()
+
+ chart_view = QChartView(self._chart)
+ chart_view.setRenderHint(QPainter.RenderHint.Antialiasing)
+
+ control_widget = QWidget(self)
+ control_layout = QGridLayout(control_widget)
+ control_layout.setColumnStretch(1, 1)
+
+ control_layout.addWidget(selected_point_index_label, 0, 0)
+ control_layout.addWidget(self._selected_point_index_lineedit, 0 , 1)
+
+ control_layout.addWidget(color_label, 1, 0)
+ control_layout.addWidget(self._color_combobox, 1 , 1)
+
+ control_layout.addWidget(size_label, 2, 0)
+ control_layout.addWidget(self._size_combobox, 2 , 1)
+
+ control_layout.addWidget(label_visibility_label, 3, 0)
+ control_layout.addWidget(self._label_visibility_checkbox, 3 , 1, 1, 2)
+
+ control_layout.addWidget(custom_label_label, 4, 0)
+ control_layout.addWidget(self._custom_label_lineedit, 4 , 1)
+
+ main_widget = QWidget(self)
+ main_layout = QHBoxLayout(main_widget)
+ main_layout.addWidget(chart_view)
+ main_layout.setStretch(0, 1)
+ main_layout.addWidget(control_widget)
+ self.setCentralWidget(main_widget)
+
+ self._series.clicked.emit(self._series.at(4))
+
+ @Slot(QPointF)
+ def _select_point(self, point: QPointF):
+ try:
+ index = self._series.points().index(point.toPoint())
+ self._series.deselectAllPoints()
+ self._series.selectPoint(index)
+ self._selectedPointIndex = index
+ self._selectedPointConfig = self._series.pointConfiguration(index)
+ selected_point = self._series.at(index)
+ self._selected_point_index_lineedit.setText("(" + str(selected_point.x()) + ", " +
+ str(selected_point.y()) + ")")
+ config = self._series.pointConfiguration(index)
+
+ try:
+ color = config[PointConfig.Color]
+ except KeyError:
+ color = self._series.color()
+ if self._color_combobox.findData(color) < 0:
+ self._color_combobox.addItem(color.name(), color)
+ self._color_combobox.setCurrentIndex(self._color_combobox.findData(color))
+
+ try:
+ size = config[PointConfig.Size]
+ except KeyError:
+ size = self._series.markerSize()
+ if self._size_combobox.findData(size) < 0:
+ self._size_combobox.addItem(str(size), size)
+ self._size_combobox.setCurrentIndex(self._size_combobox.findData(size))
+
+ try:
+ labelVisibility = config[PointConfig.LabelVisibility]
+ except KeyError:
+ labelVisibility = self._series.pointLabelsVisible()
+ self._label_visibility_checkbox.setChecked(labelVisibility)
+
+ try:
+ customLabel = config[PointConfig.LabelFormat]
+ except KeyError:
+ customLabel = ""
+ self._custom_label_lineedit.setText(customLabel)
+ except ValueError:
+ # Do nothing if the place that was clicked on wasn't a point.
+ pass
+
+ @Slot(int)
+ def _set_color(self, index: int):
+ self._selectedPointConfig[PointConfig.Color] = self._color_combobox.currentData()
+ self._series.setPointConfiguration(self._selectedPointIndex, self._selectedPointConfig)
+
+ @Slot(int)
+ def _set_size(self, index: int):
+ self._selectedPointConfig[PointConfig.Size] = self._size_combobox.currentData()
+ self._series.setPointConfiguration(self._selectedPointIndex, self._selectedPointConfig)
+
+ @Slot(bool)
+ def _set_label_visibility(self, checked: bool):
+ self._selectedPointConfig[PointConfig.LabelVisibility] = checked
+ self._series.setPointConfiguration(self._selectedPointIndex, self._selectedPointConfig)
+
+ @Slot()
+ def _set_custom_label(self):
+ self._selectedPointConfig[PointConfig.LabelFormat] = self._custom_label_lineedit.text()
+ self._series.setPointConfiguration(self._selectedPointIndex, self._selectedPointConfig)
diff --git a/examples/charts/pointconfiguration/doc/pointconfiguration.png b/examples/charts/pointconfiguration/doc/pointconfiguration.png
new file mode 100644
index 000000000..791698587
--- /dev/null
+++ b/examples/charts/pointconfiguration/doc/pointconfiguration.png
Binary files differ
diff --git a/examples/charts/pointconfiguration/doc/pointconfiguration.rst b/examples/charts/pointconfiguration/doc/pointconfiguration.rst
new file mode 100644
index 000000000..63cade471
--- /dev/null
+++ b/examples/charts/pointconfiguration/doc/pointconfiguration.rst
@@ -0,0 +1,148 @@
+.. role:: py(code)
+ :language: python
+
+Selected Point Configuration Example
+====================================
+
+This example shows how to configure individual points of a :py:`QLineSeries`.
+
+.. image:: pointconfiguration.png
+ :width: 90%
+ :align: center
+ :alt: Line chart with controls for configuring selected points
+
+Features demonstrated
+~~~~~~~~~~~~~~~~~~~~~
+
+In this application you will learn how to:
+
+* Select a series of points on click
+* Override the configuration for the following properties of specific points:
+
+ * Color
+ * Size
+ * Label visibility
+ * Text format of the label
+
+Subclass QMainWindow
+~~~~~~~~~~~~~~~~~~~~
+
+Create a subclass of :py:`QMainWindow` to contain the chart and controls.
+
+.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py
+ :linenos:
+ :lineno-start: 15
+ :lines: 15-17
+
+Create a line series
+~~~~~~~~~~~~~~~~~~~~
+
+Create a :py:`QLineSeries` containing the points to plot. Give it a name and make the points
+visible.
+
+.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py
+ :linenos:
+ :lineno-start: 20
+ :lines: 20-27
+
+Create the point configuration controls
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now, create controls to configure the color, size, and label visibility attributes of a point.
+
+#. Create an associated label for each control, so the user knows what the control does.
+#. For the color and size, use a :py:`QComboBox`, populating it with a variety of colors and size
+ choices.
+#. Create the final two controls. Create a :py:`QCheckbox` to control the visibility of the selected
+ point, and a :py:`QLineEdit` to allow the user to provide a custom label for it.
+
+.. note::
+ Do not set initial values for any of the controls, as a point will always be selected showing
+ its current settings.
+
+.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py
+ :linenos:
+ :lineno-start: 29
+ :lines: 29-52
+
+Populate the controls upon selecting a point
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Add the logic to set the current control values depending on the chosen point. Note that the whole
+series value is used if there is no customization for a selected point. In this case, if the series
+is set to show blue points, a blue color value will be shown in the color combobox.
+
+Perform some actions upon clicking on the lineseries. Look up the point clicked on and remove the
+prior point selection. Finally, select the point that was clicked on. This makes the point larger to
+indicate its selection. The current selected point's index and :py:`PointConfigurations` are saved
+to a member variable for later use.
+
+Query the :py:`PointConfigurations`, and use those to find the matching indices in the combo boxes.
+Set the current indices of the comboboxes to the corresponding values you looked up. Similarly,
+look up the values in :py:`PointConfigurations`, and update the checkbox and line edit controls.
+
+.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py
+ :linenos:
+ :lineno-start: 54
+ :lines: 54
+.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py
+ :linenos:
+ :lineno-start: 95
+ :lines: 95-137
+
+Provide the logic to configure the selected point
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Now that the controls are populated with some values, add logic to do something when the value
+changes. Connect the control signals and the logic, to configure the selected point based on the
+chosen values in the controls. You can do this by setting the :py:`QXYSeries::PointConfiguration`
+value that is associated with the control, to the :py:`m_selectedPointConfig` and
+:py:`PointConfigurations` member variables, and call :py:`QXYSeries::setPointConfiguration`.
+
+.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py
+ :linenos:
+ :lineno-start: 55
+ :lines: 55-58
+.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py
+ :linenos:
+ :lineno-start: 139
+ :lines: 139-157
+
+Create the chart and lay out the controls
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Finally, create the chart and its view, add the series to the chart, create the layout of the
+window, and select an initial point.
+
+.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py
+ :linenos:
+ :lineno-start: 60
+ :lines: 60-93
+.. literalinclude:: ../../../../examples/charts/pointconfiguration/chartwindow.py
+ :linenos:
+ :lineno-start: 159
+ :lines: 159-163
+
+In our entrypoint file `pointconfiguration.py`, instantiate the :py:`ChartWindow`, resize it, show
+it, and start the event loop.
+
+.. literalinclude:: ../../../../examples/charts/pointconfiguration/pointconfiguration.py
+ :linenos:
+ :lineno-start: 11
+ :lines: 11-17
+
+You now have a fully functioning application that demonstrates how to customize individual chart
+points.
+
+Usage
+-----
+To use this example, click any point you'd like to customize, change any of the comboboxes and
+checkboxes controlling the individual point color, size, label visibility. You can customize the
+label text in the line edit at the bottom.
+
+There are three special formatting strings for the label that you can use: ``@pointX``, ``@pointY``,
+and ``@index``. These are replaced with the x value, y value, and index of the point, respectively.
+More information about that can be found in the documentation for
+`QtCharts.QXYSeries.pointLabelsFormat`_.
+
+.. _`QtCharts.QXYSeries.pointLabelsFormat`: https://doc.qt.io/qtforpython/PySide6/QtCharts/QXYSeries.html#PySide6.QtCharts.PySide6.QtCharts.QXYSeries.pointLabelsFormat
diff --git a/examples/charts/pointconfiguration/pointconfiguration.py b/examples/charts/pointconfiguration/pointconfiguration.py
new file mode 100644
index 000000000..d8c90d2df
--- /dev/null
+++ b/examples/charts/pointconfiguration/pointconfiguration.py
@@ -0,0 +1,17 @@
+# 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.QtWidgets import QApplication
+
+from chartwindow import ChartWindow
+
+
+if __name__ == "__main__":
+
+ a = QApplication(sys.argv)
+ main_window = ChartWindow()
+ main_window.resize(640, 480)
+ main_window.show()
+ sys.exit(a.exec())
diff --git a/examples/charts/pointconfiguration/pointconfiguration.pyproject b/examples/charts/pointconfiguration/pointconfiguration.pyproject
new file mode 100644
index 000000000..c53d798be
--- /dev/null
+++ b/examples/charts/pointconfiguration/pointconfiguration.pyproject
@@ -0,0 +1,3 @@
+{
+ "files": ["pointconfiguration.py", "chartwindow.py"]
+}