C++ qpainter喷漆备选方案(Mac上的性能很差)

C++ qpainter喷漆备选方案(Mac上的性能很差),c++,performance,qt,macos,paint,C++,Performance,Qt,Macos,Paint,我有一个类,它在QWidget中显示音频文件的波形数据(参见下面widget的屏幕截图,当时我仍然使用渐变,这导致性能不佳) 使用对QPainter::drawLine的多次调用,将音频数据直接绘制在小部件上的paintEvent中(对QWidget::drawLine的最小调用量相当于小部件的宽度=>每个x坐标至少一行)。 虽然这种方法在Windows上运行得很好(全屏的paintEvent大约需要4毫秒),但在MacOS下运行该程序时,性能要差4-5倍 绘制的性能对于显示数据的流体滚动非常重

我有一个类,它在QWidget中显示音频文件的波形数据(参见下面widget的屏幕截图,当时我仍然使用渐变,这导致性能不佳)

使用对
QPainter::drawLine
的多次调用,将音频数据直接绘制在小部件上的paintEvent中(对
QWidget::drawLine
的最小调用量相当于小部件的宽度=>每个x坐标至少一行)。 虽然这种方法在Windows上运行得很好(全屏的paintEvent大约需要4毫秒),但在MacOS下运行该程序时,性能要差4-5倍

绘制的性能对于显示数据的流体滚动非常重要

所以我的问题是,是否有人知道qpaint.drawLine到绘制线的更快的替代方案(依赖于平台的解决方案可能可以,只要它们可以用于绘制事件),或者是否有方法加快滚动、某种缓冲等

当前版本(4.7.x)的Qt使用核心图形后端进行绘制。正如你发现的那样,它有时会很慢。在Windows上,它使用了一个性能非常好的软件渲染器


我的建议是不要在你的绘画活动中直接在经过的画家身上绘画。相反,创建一个与小部件绘制区域大小相同的
QImage
,并在其上绘制。这将使用更快的软件渲染器。然后在需要时将
QImage
绘制到画师上。

您可以构建一个QPainterPath并绘制它,而不是重复调用drawLine函数。而且,你可以缓存路径,这样在第一次绘制之后速度会快得多。

使用OpenGL,如果你想画得很快。

我们使用的是Qt4.4,我已经尝试过先在QPixmap上绘制数据,然后再在小部件上绘制pixmap,但加速幅度很小(QPainter::drawLine在pixmap上绘制时并没有明显加快)我记得QPixmap与QImage的不同之处在于QPixmap使用平台“加速”后端。在OS X中,这意味着它仍然是核心图形。使用QImage将确保您使用的是软件渲染器。@smerlin QPixmap优化用于在屏幕上显示图像,而QImage优化用于I/O。如果您使用QPixmap绘制线条,则速度会较慢。将QImage与
QImage::Format_ARGB32_预乘
在非常好的性能中;)简单地从
QGLWidget
而不是
QWidget
派生不起作用,因为许多绘制事件根本没有路由到小部件,此外,应用程序在MacOS上崩溃,错误消息为:“必须在QPaintDevice之前构建QApplication”,当然我已经有了一个QApplication实例。此外,我怀疑仅仅切换到OpenGL不会加快任何速度,因为我绘制的数据每帧都会发生变化,而且这些数据几乎每帧都必须上传到图形卡上?!如果使用QGLWidget,则需要使用OpenGLAPI绘制图像。画简单的多段线很容易,就像你画的那样。是的,当你的数据每一帧都改变时,数据每一帧都会被移动到图形卡的内存中,但是你的案例中的数据量应该很小,不会有问题。实际的绘图速度会非常快。qt文档说,使用QGLWidget绘制2D数据仍然应该使用QPaint完成。我不知道这一点。虽然我认为文档中说可以使用QPainter,但不应该使用它。我没有在QGLWidget中使用QPaint,所以我不知道使用QPaint或OpenGLAPI之间有什么样的性能差异。