保留以前在QQuickPaintedItem中绘制的数据

时间:2015-11-17 12:00:11

标签: qt qml qt5 qtquick2 qpainter

我有一个自定义QML组件来绘制从QQuickPaintedItem派生的图表。在paint方法中,我遍历坐标列表并绘制它们。我的paint()如下

QRectF bounds = boundingRect();
float w = bounds.width();
float h = bounds.height();
float dx = w / listSize;

for(int i = 0; i < coordinatesList.size() - 1; ++i)
{
    QPointF m_p1(dx*i, (h/2)-(coordinatesList.at(i)*(h/4)));
    QPointF m_p2(dx*(i+1), (h/2)-(coordinatesList.at(i+1)*(h/4)));
    painter->drawLine(m_p1, m_p2);
}

有没有办法保留以前绘制的点数,这样我就不必重新绘制整个点列表而只重绘特定点?

2 个答案:

答案 0 :(得分:2)

我现在无法测试它,但您可以在QPixmap

上绘制所有点
m_pixmap.fill();
QPainter buffer(&m_pixmap);
....
buffer->drawLine(...);
...

然后在Canvas上绘制保存的像素图。

painter->drawPixmap(0, 0, m_pixmap);

在下一个绘画请求中,您只需绘制已保存的QPixmap。只有在情节发生变化时,QPixmap本身才需要重新绘制。

答案 1 :(得分:1)

正如第一个答案所示,缓存是关键,但是,默认情况下使用QPixmap 这将使用不是最佳的光栅画家后端,因为它将涉及昂贵的ram到GPU ram传输。此外,虽然光栅画家提供更好的质量,但它通常比GL后端慢。

如果效率是关键,那么正确的方法是使用QOpenGLFramebufferObject,使用QPainterQOpenGLPaintDevice进行绘制,并在QQuickPaintedItem::paint()中使用原生渲染在使用FBO目标的QQuickItem上绘制FBO。这将为您提供更好的绘画性能,并避免ram到vram传输的开销。

此外,在处理绘图组件时,最好划分绘图,例如网格或刻度等内容应该是单独的组件,因为它们不需要不断重绘,只绘制实际波形和把它写在最上面。