如何在PySide6 QChart的系列数据点上添加文本?附测试代码
在PySide6 QChart数据点添加文本及自定义图例文本框的实现
一、数据点文本添加的问题修复与优化
你的测试代码中,数据点文本位置不准确的核心原因是在Chart完成布局前调用了mapToPosition,且未处理窗口缩放时的位置更新。以下是修正方案:
关键修复点:
- 延迟获取数据点的场景位置,确保Chart已完成布局
- 调整文本锚点,避免覆盖数据点
- 监听窗口缩放事件,实时更新文本位置
二、自定义图例文本框的实现
如果需要添加独立于系列图例的文本框,可以直接创建带样式的QGraphicsTextItem,或者修改现有图例的标记文本。
完整可运行代码
import sys from PySide6.QtCharts import * from PySide6.QtWidgets import * from PySide6.QtCore import * from PySide6.QtGui import * class CustomChartView(QChartView): def __init__(self, chart, target_point, text_item, parent=None): super().__init__(chart, parent) self.target_point = target_point self.text_item = text_item # 延迟更新文本位置,确保Chart布局完成 QTimer.singleShot(100, self.update_text_position) def resizeEvent(self, event): super().resizeEvent(event) # 窗口缩放时更新文本位置 self.update_text_position() def update_text_position(self): # 将数据点坐标转换为场景坐标 position = self.chart().mapToPosition(self.target_point, self.chart().series()[0]) # 调整文本位置,让文本在数据点上方居中显示 text_rect = self.text_item.boundingRect() self.text_item.setPos(position.x() - text_rect.width()/2, position.y() - text_rect.height() - 5) app = QApplication(sys.argv) # 创建系列与数据点 series = QLineSeries() series.append(0, 1) target_point = QPointF(1, 3) series.append(target_point) series.append(2, 2) # 创建Chart与坐标轴 chart = QChart() axis_x = QValueAxis() axis_y = QValueAxis() chart.addAxis(axis_x, Qt.AlignBottom) chart.addAxis(axis_y, Qt.AlignLeft) chart.addSeries(series) series.attachAxis(axis_x) series.attachAxis(axis_y) chart.setTitle("带数据点文本的折线图") # 创建数据点文本 text_item = QGraphicsTextItem("峰值点") text_item.setDefaultTextColor(QColor(255, 0, 0)) text_item.setFont(QFont("Arial", 10, QFont.Bold)) # 创建自定义图例文本框 legend_text = QGraphicsTextItem("额外信息:\n- 采集时间:2024-05-20\n- 数据来源:传感器") legend_text.setDefaultTextColor(QColor(0, 128, 0)) legend_text.setFont(QFont("Arial", 9)) # 设置文本框背景 bg_rect = QGraphicsRectItem(legend_text.boundingRect().adjusted(-5, -5, 5, 5)) bg_rect.setBrush(QColor(240, 248, 255)) bg_rect.setPen(QPen(Qt.NoPen)) bg_rect.setParentItem(legend_text) # 将文本框放在图例下方 QTimer.singleShot(100, lambda: legend_text.setPos( chart.legend().pos().x(), chart.legend().pos().y() + chart.legend().boundingRect().height() + 10 )) # 创建自定义ChartView chartView = CustomChartView(chart, target_point, text_item) chartView.setRenderHint(QPainter.Antialiasing) # 添加文本到场景 chartView.scene().addItem(text_item) chartView.scene().addItem(legend_text) # 主窗口设置 window = QMainWindow() window.setCentralWidget(chartView) window.resize(600, 400) window.show() sys.exit(app.exec())
代码说明:
数据点文本:
- 自定义
CustomChartView类,重写resizeEvent实现窗口缩放时的位置更新 - 用
QTimer.singleShot延迟获取位置,确保Chart完成布局 - 调整文本位置使其在数据点上方居中,避免覆盖
- 自定义
自定义图例文本框:
- 创建带背景的文本框,设置样式区分于默认图例
- 延迟定位到图例下方,确保图例位置已确定
- 支持多行文本展示额外信息
内容的提问来源于stack exchange,提问作者Tom Woodland
相关产品推荐
相关产品推荐

