使用OpenGL加速
在图表中的数据点很多的时候,比如有多个图表,每个图表的的数据点达到几万甚至到10万的时候,不使用GPU加速,渲染速度明显变慢,QChart提供了使用OpenGL进行图表渲染加速,在下面的测试中,我们可以看到,使用 OpenGL进行渲染加速,图表渲染的FPS(每秒帧率)会有数量级的提高。
在QChart中,使用图表序列类的方法setUseOpenGL()可以很方便地打开和关闭OpenGL加速功能。
OpenGL加速示例
示例说明如何为QLineSeries和QScatterSeries启用OpenGL加速。完整代码如下:
import sys,math
from PyQt5.QtCore import Qt, QObject, QTimer,QPointF, QElapsedTimer, QRandomGenerator
from PyQt5.QtGui import QPainter, QPen, QBrush, QColor
from PyQt5.QtWidgets import QApplication, QMainWindow, QGraphicsView, QLabel
from PyQt5.QtChart import QChart, QChartView,QLineSeries, QValueAxis, QXYSeries, QScatterSeries
class DataSource(QObject):
frameCount = 0
def __init__(self, parent = None):
super(DataSource, self).__init__(parent)
self.index = -1
self.data = []
self.seriesList = []
self.fpsTimer = QElapsedTimer()
self.dataUpdater = QTimer()
self.fpsLabel = None
def update(self, series, seriesIndex):
if not series is None:
seriesData = self.data[seriesIndex]
if seriesIndex == 0:
self.index += 1
if self.index > len(seriesData) - 1:
self.index = 0
points = seriesData[self.index]
# 性能优化, 使用replace代替clear + append
series.replace(points)
def handleSceneChanged(self):
self.dataUpdater.start()
def updateAllSeries(self):
for i, series in enumerate(self.seriesList):
self.update(series, i)
self.frameCount += 1
elapsed = self.fpsTimer.elapsed()
if elapsed >= 1000:
elapsed = self.fpsTimer.restart()
fps = (1000.0 * self.frameCount) / elapsed
if not self.fpsLabel is None:
self.fpsLabel.setText('FPS: %.1f' % fps)
self.fpsLabel.adjustSize()
self.frameCount = 0
def startUpdates(self, seriesList, fpsLabel):
self.seriesList = seriesList
self.fpsLabel = fpsLabel
self.dataUpdater.setInterval(0)
self.dataUpdater.setSingleShot(True)
self.dataUpdater.timeout.connect(self.updateAllSeries)
self.fpsTimer.start()
self.updateAllSeries()
def generateData(self, seriesCount, rowCount, colCount):
self.data.clear()
xAdjustment = 20.0 / (colCount * rowCount)
yMultiplier = 3.0 / seriesCount
#根据类型追加新数据
for k in range (seriesCount):
seriesData = []
height = k * (10.0 / seriesCount) + 0.3
for i in range (rowCount):
points = []
#points.reverse(colCount)
for j in range (colCount):
y = height + yMultiplier * ( math.sin(math.pi/50*j) + QRandomGenerator.global_().generateDouble())
x = 0.000001 + 20.0 * ( j / colCount ) + (xAdjustment * i)
points.append(QPointF(x, y))
seriesData.append(points)
self.data.append(seriesData)
class DemoOpenGLSeries(QMainWindow):
def __init__(self, parent=None):
super(DemoOpenGLSeries, self).__init__(parent)
# 设置窗口标题
self.setWindowTitle('实战 Qt for Python: 使用OpenGL加速')
# 设置窗口大小
self.resize(600, 400)
self.createChart()
def createChart(self):
colors = [Qt.red, Qt.blue, Qt.green, Qt.black]
chart = QChart()
chart.setTitle('Open GL 加速')
chart.legend().hide()
axisX = QValueAxis()
axisY = QValueAxis()
chart.addAxis(axisX, Qt.AlignBottom)
chart.addAxis(axisY, Qt.AlignLeft)
seriesCount = 10
pointCount = 10000
self.seriesList = []
for i in range(seriesCount):
colorIndex = i % len(colors)
if (i % 2) == 0:
series = QLineSeries()
series.setPen(QPen(QBrush(colors[colorIndex]), (colorIndex + 2) / 2))
else:
series = QScatterSeries()
series.setColor(colors[colorIndex])
series.setMarkerSize((colorIndex+2)/2.0)
series.setPen(QPen(Qt.black))
self.seriesList.append(series)
#可以注释掉这一句来观察OpenGL的加速效果
series.setUseOpenGL(True) #!!!!!!
chart.addSeries(series)
series.attachAxis(axisX)
series.attachAxis(axisY)
axisX.setRange(0, 20.0)
axisY.setRange(0, 10.0)
chartView =QChartView(chart)
#chartView.setRenderHint(QPainter.Antialiasing)
self.setCentralWidget(chartView)
self.dataSource = DataSource()
self.dataSource.generateData(seriesCount, 10, pointCount)
fpsLabel = QLabel(self)
countLabel = QLabel(self)
countLabel.setText('总点数 %d' % (pointCount * seriesCount))
countLabel.adjustSize()
fpsLabel.move(10, 2)
fpsLabel.adjustSize()
fpsLabel.raise_()
fpsLabel.show()
countLabel.move(10, fpsLabel.height())
fpsLabel.raise_()
countLabel.show()
chart.scene().changed.connect(self.dataSource.handleSceneChanged)
self.dataSource.startUpdates(self.seriesList, fpsLabel)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = DemoOpenGLSeries()
window.show()
sys.exit(app.exec()) 运行结果如下图:

OpenGL加速图表绘制
本文知识点
- 使用OpenGL加速渲染图表
版权声明:本文为seniorwizard原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。