QtQuick 提供的 QtChart 可以满足在 Qml 中高效绘制动态曲线,但由于它是 GPL 协议,故应用场景有限。
Canvas 绘图
Qml 中提供了 Canvas 组件,可以直接使用 js 进行绘制,比如下面几行代码,便可以绘制多条动态曲线:
1 | Canvas { |
其显示效果如下: 但由于其在实际运行过程中,是由 CPU 来解析脚本再来执行,其运行效率极为低下 。
其它的选择
为了能够高效的显示动态曲线,目前有以下几种选择方式: -
QQuickPaintedItem :通过继承 QQuickPaintedItem 来重载其
paint
函数,使用 QPainter 完成图形绘制。 - QOpenGLWindow :
通过继承自 QOpenGLWindow 来直接调用 OpenGL API 完成图形绘制 -
QQuickFrameBufferObject :实现
QQuickFramebufferObject::Renderer
类来完成图形绘制
Qml Shape 也是个高效组件,但是它无法用来显示动态曲线
QPainter 其使用 CPU 来渲染无法很好的利用 GPU,虽然比起 Canvas 好得多,但也不够高效。
OpenGL 相关 API 不是太好懂,编写起来比较吃力……
QNanoPainter
QNanoPainter 则很好的解决上面的问题: 1. 基于 NanoVG 实现了自己的 QNanoPainter,以尽量以 GPU 直接渲染 2. 提供 Canvas API,可以很好的将 Qml API 重构
对于上面显示的曲线,对应的代码如下: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29void NanoCurvePainter::DrawLines(float ref, QNanoPainter* painter) {
if (curve_data_.size() <= 1) {
return;
}
painter->setStrokeStyle(QNanoColor(255, 255, 0));
painter->setLineWidth(1);
painter->beginPath();
painter->moveTo(0,
GetPointY(ref, curve_data_.at(0)));
for (int i = 1; i < curve_data_.size(); ++i) {
painter->lineTo(i,
GetPointY(ref, curve_data_.at(i)));
}
painter->stroke();
}
void NanoCurvePainter::paint(QNanoPainter* painter) {
DrawLines(0, painter);
DrawLines(20, painter);
DrawLines(-20, painter);
DrawLines(30, painter);
DrawLines(-30, painter);
}
经过测试,相比 Canvas 绘图,QNanoPainter 消耗 CPU 为前者的 ⅓ 。