选择点配置示例#
此示例展示了如何配置QLineSeries
的各个点的配置。
展示的功能#
在这款应用中,您将学习如何
在点击时选择一系列点
覆盖以下特定点的配置
颜色
大小
标签可见性
标签文本格式
子类化QMainWindow#
创建一个QMainWindow的子类,用于包含图表和控制功能。
16class ChartWindow(QMainWindow):
17 def __init__(self, parent=None):
18 super().__init__(parent)
创建一个折线序列#
创建一个包含点的折线序列以进行绘制。给它一个名称并使点可见。
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: Union[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
,调整其大小,显示它,并启动事件循环。
11if __name__ == "__main__":
12
13 a = QApplication(sys.argv)
14 main_window = ChartWindow()
15 main_window.resize(640, 480)
16 main_window.show()
17 sys.exit(a.exec())
现在您拥有了一个完全功能的应用程序,该应用程序演示了如何自定义单个图表点。
使用方法#
要使用此示例,单击您想要自定义的任何点,更改任何控制单个点颜色、大小和标签可见性的组合框和复选框。您可以在底部的行编辑中自定义标签文本。
您可以使用三个特殊的格式化字符串用于标签:@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
"""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
"""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
from typing import Union
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: Union[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)