选点配置示例¶
此示例展示了如何配置QLineSeries
的各个点。

展示的功能¶
在这个应用程序中,您将学习如何:
点击选择一系列点
覆盖特定点的以下属性的配置:
颜色
大小
标签可见性
标签的文本格式
子类化 QMainWindow¶
创建一个QMainWindow
的子类来包含图表和控件。
16class ChartWindow(QMainWindow):
17 def __init__(self, parent=None):
18 super().__init__(parent)
创建一个线系列¶
创建一个包含要绘制的点的QLineSeries
。给它一个名称并使点可见。
20 self.setWindowTitle("Chart")
21 self._series = QLineSeries(self)
22 self._series.setName("Customized series")
23 self._series.setPointsVisible(True)
24 self._series.append([QPointF(0, 7), QPointF(2, 4),
25 QPointF(3, 5), QPointF(7, 4),
26 QPointF(10, 5), QPointF(11, 1),
27 QPointF(13, 3), QPointF(17, 6),
28 QPointF(18, 3), QPointF(20, 2)])
创建点配置控件¶
现在,创建控件来配置点的颜色、大小和标签可见性属性。
为每个控件创建一个关联的标签,以便用户知道该控件的作用。
对于颜色和大小,使用一个
QComboBox
,并用各种颜色和大小选项填充它。创建最后两个控件。创建一个
QCheckbox
来控制所选点的可见性,以及一个QLineEdit
以允许用户为其提供自定义标签。
注意
不要为任何控件设置初始值,因为总是会选择一个点来显示其当前设置。
31 self._selected_point_index_lineedit = QLineEdit()
32 self._selected_point_index_lineedit.setReadOnly(True)
33 self._selected_point_index_lineedit.setStyleSheet(
34 "background-color: rgba(0, 0, 0, 0); border: 0px")
35
36 color_label = QLabel("Color: ")
37 self._color_combobox = QComboBox()
38 color_strings = ["red", "orange", "yellow", "green", "blue",
39 "indigo", "violet", "black"]
40 for color_str in color_strings:
41 self._color_combobox.addItem(QIcon(), color_str, QColor(color_str))
42
43 size_label = QLabel("Size: ")
44 self._size_combobox = QComboBox()
45 for size in [2, 3, 4, 6, 8, 10, 12, 15]:
46 self._size_combobox.addItem(QIcon(), str(size), size)
47
48 label_visibility_label = QLabel("Label Visibility: ")
49 self._label_visibility_checkbox = QCheckBox()
50
51 custom_label_label = QLabel("Custom Label: ")
52 self._custom_label_lineedit = QLineEdit()
在选择一个点时填充控件¶
添加逻辑以根据所选点设置当前控件值。请注意,如果没有为所选点进行自定义,则使用整个系列的值。在这种情况下,如果系列设置为显示蓝色点,颜色组合框中将显示蓝色值。
点击线条系列时执行一些操作。查找点击的点并移除之前选择的点。最后,选择被点击的点。这会使该点变大以指示其被选中。当前选中点的索引和PointConfigurations
被保存到一个成员变量中供以后使用。
查询PointConfigurations
,并使用这些信息在组合框中找到匹配的索引。
将组合框的当前索引设置为您查找的相应值。同样地,
查找PointConfigurations
中的值,并更新复选框和行编辑控件。
54 self._series.clicked.connect(self._select_point)
97 @Slot(QPointF)
98 def _select_point(self, point: QPointF | int):
99 try:
100 index = (self._series.points().index(point.toPoint()) if
101 isinstance(point, QPointF) else point)
102 except ValueError:
103 # Do nothing if the place that was clicked on wasn't a point.
104 return
105
106 self._series.deselectAllPoints()
107 self._series.selectPoint(index)
108 self._selectedPointIndex = index
109 self._selectedPointConfig = self._series.pointConfiguration(index)
110 selected_point = self._series.at(index)
111 selected_index_lineedit = self._selected_point_index_lineedit
112 selected_index_lineedit.setText("(" + str(selected_point.x()) + ", "
113 + str(selected_point.y()) + ")")
114 config = self._series.pointConfiguration(index)
115
116 color = config.get(PointConfig.Color) or self._series.color()
117 size = config.get(PointConfig.Size) or self._series.markerSize()
118 labelVisibility = (config.get(PointConfig.LabelVisibility)
119 or self._series.pointLabelsVisible())
120 customLabel = config.get(PointConfig.LabelFormat) or ""
121
122 combobox_value_list = [
123 (self._color_combobox, color.name(), color),
124 (self._size_combobox, str(size), size)
125 ]
126 for box, value_str, value in combobox_value_list:
127 if box.findData(value) < 0:
128 box.addItem(value_str, value)
129 box.setCurrentIndex(box.findData(value))
130
131 self._label_visibility_checkbox.setChecked(labelVisibility)
132 self._custom_label_lineedit.setText(customLabel)
提供配置选定点的逻辑¶
现在控件已经填充了一些值,添加逻辑以在值更改时执行某些操作。连接控件信号和逻辑,根据控件中选择的值配置所选点。您可以通过将与控件关联的QXYSeries::PointConfiguration
值设置为m_selectedPointConfig
和PointConfigurations
成员变量,并调用QXYSeries::setPointConfiguration
来实现这一点。
55 self._color_combobox.activated.connect(self._set_color)
56 self._size_combobox.activated.connect(self._set_size)
57 label_vis_checkbox = self._label_visibility_checkbox
58 label_vis_checkbox.clicked.connect(self._set_label_visibility)
59 clabel_lineedit = self._custom_label_lineedit
60 clabel_lineedit.editingFinished.connect(self._set_custom_label)
140 @Slot(int)
141 def _set_size(self, index: int):
142 spc = self._selectedPointConfig
143 spc[PointConfig.Size] = self._size_combobox.currentData()
144 self._series.setPointConfiguration(self._selectedPointIndex, spc)
145
146 @Slot(bool)
147 def _set_label_visibility(self, checked: bool):
148 spc = self._selectedPointConfig
149 spc[PointConfig.LabelVisibility] = checked
150 self._series.setPointConfiguration(self._selectedPointIndex, spc)
151
152 @Slot()
153 def _set_custom_label(self):
154 spc = self._selectedPointConfig
155 spc[PointConfig.LabelFormat] = self._custom_label_lineedit.text()
156 self._series.setPointConfiguration(self._selectedPointIndex, spc)
创建图表并布局控件¶
最后,创建图表及其视图,将系列添加到图表中,创建窗口的布局,并选择一个初始点。
62 self._chart = QChart()
63 self._chart.addSeries(self._series)
64 self._chart.createDefaultAxes()
65
66 chart_view = QChartView(self._chart)
67 chart_view.setRenderHint(QPainter.RenderHint.Antialiasing)
68
69 control_widget = QWidget(self)
70 control_layout = QGridLayout(control_widget)
71 control_layout.setColumnStretch(1, 1)
72
73 control_layout.addWidget(selected_point_index_label, 0, 0)
74 control_layout.addWidget(self._selected_point_index_lineedit, 0, 1)
75
76 control_layout.addWidget(color_label, 1, 0)
77 control_layout.addWidget(self._color_combobox, 1, 1)
78
79 control_layout.addWidget(size_label, 2, 0)
80 control_layout.addWidget(self._size_combobox, 2, 1)
81
82 control_layout.addWidget(label_visibility_label, 3, 0)
83 control_layout.addWidget(self._label_visibility_checkbox, 3, 1, 1, 2)
84
85 control_layout.addWidget(custom_label_label, 4, 0)
86 control_layout.addWidget(self._custom_label_lineedit, 4, 1)
87
88 main_widget = QWidget(self)
89 main_layout = QHBoxLayout(main_widget)
90 main_layout.addWidget(chart_view)
91 main_layout.setStretch(0, 1)
92 main_layout.addWidget(control_widget)
93 self.setCentralWidget(main_widget)
94
95 self._select_point(4)
在我们的入口文件 pointconfiguration.py 中,实例化 ChartWindow
,调整其大小,显示它,并启动事件循环。
11
12if __name__ == "__main__":
13
14 a = QApplication(sys.argv)
15 main_window = ChartWindow()
16 main_window.resize(640, 480)
17 main_window.show()
你现在有一个完全功能的应用程序,展示了如何自定义单个图表点。
用法¶
要使用此示例,请单击您想要自定义的任何点,更改控制单个点颜色、大小、标签可见性的任何组合框和复选框。您可以在底部的行编辑中自定义标签文本。
标签有三种特殊的格式化字符串可以使用:@pointX
, @pointY
,
和 @index
。这些分别被替换为点的x值、y值和索引。
更多相关信息可以在
QtCharts.QXYSeries.pointLabelsFormat的文档中找到。
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from __future__ import annotations
"""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())
# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
from __future__ import annotations
"""PySide6 port of the Selected Point Configuration Example from Qt 6.5"""
from PySide6.QtCore import 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=None):
super().__init__(parent)
self.setWindowTitle("Chart")
self._series = QLineSeries(self)
self._series.setName("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("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("Color: ")
self._color_combobox = QComboBox()
color_strings = ["red", "orange", "yellow", "green", "blue",
"indigo", "violet", "black"]
for color_str in color_strings:
self._color_combobox.addItem(QIcon(), color_str, QColor(color_str))
size_label = QLabel("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("Label Visibility: ")
self._label_visibility_checkbox = QCheckBox()
custom_label_label = QLabel("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)
label_vis_checkbox = self._label_visibility_checkbox
label_vis_checkbox.clicked.connect(self._set_label_visibility)
clabel_lineedit = self._custom_label_lineedit
clabel_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._select_point(4)
@Slot(QPointF)
def _select_point(self, point: QPointF | int):
try:
index = (self._series.points().index(point.toPoint()) if
isinstance(point, QPointF) else point)
except ValueError:
# Do nothing if the place that was clicked on wasn't a point.
return
self._series.deselectAllPoints()
self._series.selectPoint(index)
self._selectedPointIndex = index
self._selectedPointConfig = self._series.pointConfiguration(index)
selected_point = self._series.at(index)
selected_index_lineedit = self._selected_point_index_lineedit
selected_index_lineedit.setText("(" + str(selected_point.x()) + ", "
+ str(selected_point.y()) + ")")
config = self._series.pointConfiguration(index)
color = config.get(PointConfig.Color) or self._series.color()
size = config.get(PointConfig.Size) or self._series.markerSize()
labelVisibility = (config.get(PointConfig.LabelVisibility)
or self._series.pointLabelsVisible())
customLabel = config.get(PointConfig.LabelFormat) or ""
combobox_value_list = [
(self._color_combobox, color.name(), color),
(self._size_combobox, str(size), size)
]
for box, value_str, value in combobox_value_list:
if box.findData(value) < 0:
box.addItem(value_str, value)
box.setCurrentIndex(box.findData(value))
self._label_visibility_checkbox.setChecked(labelVisibility)
self._custom_label_lineedit.setText(customLabel)
@Slot(int)
def _set_color(self, index: int):
spc = self._selectedPointConfig
spc[PointConfig.Color] = self._color_combobox.currentData()
self._series.setPointConfiguration(self._selectedPointIndex, spc)
@Slot(int)
def _set_size(self, index: int):
spc = self._selectedPointConfig
spc[PointConfig.Size] = self._size_combobox.currentData()
self._series.setPointConfiguration(self._selectedPointIndex, spc)
@Slot(bool)
def _set_label_visibility(self, checked: bool):
spc = self._selectedPointConfig
spc[PointConfig.LabelVisibility] = checked
self._series.setPointConfiguration(self._selectedPointIndex, spc)
@Slot()
def _set_custom_label(self):
spc = self._selectedPointConfig
spc[PointConfig.LabelFormat] = self._custom_label_lineedit.text()
self._series.setPointConfiguration(self._selectedPointIndex, spc)