如何在 QHorizontalBarSeries/QChart 上指定的 x 值处画一条垂直线?
How to draw a vertical line at specified x value on QHorizontalBarSeries/QChart?
我按照 this example 创建了一个水平条形图。我想在 x 轴的特定值处绘制一条静态垂直线。我试过向 QChart 添加 QLineSeries,但没有显示任何内容。我在 Python 中这样做,但 C++ 也可以。
一个可能的解决方案是覆盖绘制垂直线的 drawForeground() 方法,计算位置必须使用 mapToPosition() 方法:
import sys
from PyQt5.QtCore import Qt, QPointF
from PyQt5.QtGui import QColor, QPainter, QPen
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtChart import (
QBarCategoryAxis,
QBarSet,
QChart,
QHorizontalBarSeries,
QChartView,
QValueAxis,
)
class ChartView(QChartView):
_x = None
@property
def x(self):
return self._x
@x.setter
def x(self, x):
self._x = x
self.update()
def drawForeground(self, painter, rect):
if self.x is None:
return
painter.save()
pen = QPen(QColor("indigo"))
pen.setWidth(3)
painter.setPen(pen)
p = self.chart().mapToPosition(QPointF(self.x, 0))
r = self.chart().plotArea()
p1 = QPointF(p.x(), r.top())
p2 = QPointF(p.x(), r.bottom())
painter.drawLine(p1, p2)
painter.restore()
def main():
app = QApplication(sys.argv)
set0 = QBarSet("Jane")
set1 = QBarSet("John")
set2 = QBarSet("Axel")
set3 = QBarSet("Mary")
set4 = QBarSet("Samantha")
set0 << 1 << 2 << 3 << 4 << 5 << 6
set1 << 5 << 0 << 0 << 4 << 0 << 7
set2 << 3 << 5 << 8 << 13 << 8 << 5
set3 << 5 << 6 << 7 << 3 << 4 << 5
set4 << 9 << 7 << 5 << 3 << 1 << 2
series = QHorizontalBarSeries()
series.append(set0)
series.append(set1)
series.append(set2)
series.append(set3)
series.append(set4)
chart = QChart()
chart.addSeries(series)
chart.setTitle("Simple horizontal barchart example")
chart.setAnimationOptions(QChart.SeriesAnimations)
categories = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
axisY = QBarCategoryAxis()
axisY.append(categories)
chart.addAxis(axisY, Qt.AlignLeft)
series.attachAxis(axisY)
axisX = QValueAxis()
chart.addAxis(axisX, Qt.AlignBottom)
series.attachAxis(axisX)
axisX.applyNiceNumbers()
chart.legend().setVisible(True)
chart.legend().setAlignment(Qt.AlignBottom)
chartView = ChartView(chart)
chartView.setRenderHint(QPainter.Antialiasing)
chartView.x = 11.5
window = QMainWindow()
window.setCentralWidget(chartView)
window.resize(420, 300)
window.show()
app.exec()
if __name__ == "__main__":
main()
我按照 this example 创建了一个水平条形图。我想在 x 轴的特定值处绘制一条静态垂直线。我试过向 QChart 添加 QLineSeries,但没有显示任何内容。我在 Python 中这样做,但 C++ 也可以。
一个可能的解决方案是覆盖绘制垂直线的 drawForeground() 方法,计算位置必须使用 mapToPosition() 方法:
import sys
from PyQt5.QtCore import Qt, QPointF
from PyQt5.QtGui import QColor, QPainter, QPen
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtChart import (
QBarCategoryAxis,
QBarSet,
QChart,
QHorizontalBarSeries,
QChartView,
QValueAxis,
)
class ChartView(QChartView):
_x = None
@property
def x(self):
return self._x
@x.setter
def x(self, x):
self._x = x
self.update()
def drawForeground(self, painter, rect):
if self.x is None:
return
painter.save()
pen = QPen(QColor("indigo"))
pen.setWidth(3)
painter.setPen(pen)
p = self.chart().mapToPosition(QPointF(self.x, 0))
r = self.chart().plotArea()
p1 = QPointF(p.x(), r.top())
p2 = QPointF(p.x(), r.bottom())
painter.drawLine(p1, p2)
painter.restore()
def main():
app = QApplication(sys.argv)
set0 = QBarSet("Jane")
set1 = QBarSet("John")
set2 = QBarSet("Axel")
set3 = QBarSet("Mary")
set4 = QBarSet("Samantha")
set0 << 1 << 2 << 3 << 4 << 5 << 6
set1 << 5 << 0 << 0 << 4 << 0 << 7
set2 << 3 << 5 << 8 << 13 << 8 << 5
set3 << 5 << 6 << 7 << 3 << 4 << 5
set4 << 9 << 7 << 5 << 3 << 1 << 2
series = QHorizontalBarSeries()
series.append(set0)
series.append(set1)
series.append(set2)
series.append(set3)
series.append(set4)
chart = QChart()
chart.addSeries(series)
chart.setTitle("Simple horizontal barchart example")
chart.setAnimationOptions(QChart.SeriesAnimations)
categories = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
axisY = QBarCategoryAxis()
axisY.append(categories)
chart.addAxis(axisY, Qt.AlignLeft)
series.attachAxis(axisY)
axisX = QValueAxis()
chart.addAxis(axisX, Qt.AlignBottom)
series.attachAxis(axisX)
axisX.applyNiceNumbers()
chart.legend().setVisible(True)
chart.legend().setAlignment(Qt.AlignBottom)
chartView = ChartView(chart)
chartView.setRenderHint(QPainter.Antialiasing)
chartView.x = 11.5
window = QMainWindow()
window.setCentralWidget(chartView)
window.resize(420, 300)
window.show()
app.exec()
if __name__ == "__main__":
main()