亮标记器和点选择示例#

亮标记器和点选择示例显示如何在系列中使用亮标记器和点选择。

QChart with Light Markers shown

创建图表及其元素#

我们首先创建一个系列,填充数据,并启用亮标记器和点选择功能。请勿将点可见性设置为True,因为亮标记器功能是一个独立的功能,同时设置两者会导致不希望的行为。

20
21    marker_size = 20.
22    series = QSplineSeries()
23    series.append([QPointF(0, 0),
24                   QPointF(0.5, 2.27),
25                   QPointF(1.5, 2.2),
26                   QPointF(3.3, 1.7),
27                   QPointF(4.23, 3.1),
28                   QPointF(5.3, 2.3),
29                   QPointF(6.47, 4.1)])
30    series.setMarkerSize(marker_size)
31    series.setLightMarker(Utilities.default_light_marker(marker_size))
32    series.setSelectedLightMarker(Utilities.default_selected_light_marker(marker_size))
33
34    @Slot(QPointF)
35    def toggle_selection(point):
36        try:
37            index = series.points().index(point)
38            if index != -1:
39                series.toggleSelection([index])
40        except ValueError:
41            pass
42

然后我们创建QChartQChartview和控制小部件及其布局,以布置自定义元素。

44
45    chart = QChart()
46    chart.addSeries(series)
47    chart.createDefaultAxes()
48    chart.legend().setVisible(False)
49
50    chart_view = QChartView(chart)
51    chart_view.setRenderHint(QPainter.Antialiasing)
52
53    control_widget = QWidget(window)

创建配置图表的UI#

接下来的步骤是我们创建允许自定义图表的用户界面元素,包括设置亮标记器和选择标记图像。

54    control_layout = QGridLayout(control_widget)
55    char_point_combobox = QComboBox()
56    char_point_selected_combobox = QComboBox()
57    line_color_combobox = QComboBox()

我们为标记选择组合框创建标签并填充项目。然后,我们为组合框提供功能,允许用户的选择来设置所需的光标记图像。由于通过设置有效的QImage或设置空的QImage()来启用和禁用光标记,因此我们需要确保如果用户不想显示未选择的点,我们实际上不设置光标记图像。如果不进行检查,将设置新的QImage作为光标记,即使它已被关闭,未选择的点也会可见。

59
60    @Slot(int)
61    def set_light_marker(index):
62        if show_unselected_points_checkbox.isChecked():
63            series.setLightMarker(Utilities.get_point_representation(
64                Utilities.point_type(index), marker_size))
65
66    char_point = QLabel("Char point: ")
67    char_point_combobox.addItems(["Red rectangle", "Green triangle", "Orange circle"])

几乎相同的程序适用于选定点光标记和线路颜色。唯一的区别是无需检查未选择点的可见性,因为它不影响功能。

70    @Slot(int)
71    def set_selected_light_marker(index):
72        series.setSelectedLightMarker(
73            Utilities.get_selected_point_representation(
74                Utilities.selected_point_type(index), marker_size))
75
76    char_point_selected = QLabel("Char point selected: ")
77    char_point_selected_combobox.addItems(["Blue triangle", "Yellow rectangle", "Lavender circle"])
78    char_point_selected_combobox.currentIndexChanged.connect(set_selected_light_marker)
79
80    @Slot(int)
81    def set_line_color(index):
82        series.setColor(Utilities.make_line_color(Utilities.line_color(index)))
83
84    line_color_label = QLabel("Line color: ")
85    line_color_combobox.addItems(["Blue", "Black", "Mint"])

未选择点可见性的改变有一点不同。正如之前提到的,通过将光标记设置为空的QImage()来使光标记不可见。这就是为什么,根据复选框的状态,选定点光标记被设置为空的QImage或从相应组合框的当前索引提取的光标记。

88    @Slot(int)
89    def display_unselected_points(checkbox_state):
90        if checkbox_state:
91            series.setLightMarker(
92                Utilities.get_point_representation(
93                    Utilities.point_type(char_point_combobox.currentIndex()), marker_size))
94        else:
95            series.setLightMarker(QImage())
96
97    show_unselected_points_label = QLabel("Display unselected points: ")

最后一部分是将小部件布局在主小部件中并设置主窗口大小。

用法#

要使用此示例,更改控制标记、线路颜色和未选择点可见性的右侧的任何组合框和复选框。然后尝试在图表上单击点以选择或取消选择它们。

下载 此示例

# 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())
# 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  # noqa: F401


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]
<RCC>
    <qresource prefix="/">
        <file>images/blue_triangle.png</file>
        <file>images/green_triangle.png</file>
    </qresource>
</RCC>