2011-05-22 113 views
7

我有一个类,它显示了QWidget中的audiofiles的波形数据(请参阅下面的小部件的屏幕截图,那时我仍然使用渐变,这导致了糟糕的性能)。qpainter绘画替代品(在Mac上表现糟糕)

的音频数据在的paintEvent绘直接使用多次调用QPainter::drawLine微件(呼叫的最小量QWidget::drawLine相当于插件=>至少一条线的宽度对于每个x坐标)。 虽然这种方法在Windows上运行得非常好(全屏幕中的paintEvent大约需要4ms),但是当程序在MacOS下运行时,性能会降低4-5倍。

绘画的性能对于显示数据的流体滚动很重要。

所以我的问题是,有没有人知道一个更快的替代QPainter.drawLine绘制线(平台相关的解决方案可能是好的,只要他们可以在paintEvent中使用),或有一种方法来加速滚动,某种缓冲等?

old screenshot of the widget (still used gradients, which caused poor performance)

回答

4

的Qt的最新版本(4.7.x)使用​​核芯显卡后端绘画。有时你发现它会变慢。在Windows上,它使用了一个性能非常好的软件渲染器。

我的建议是不要在绘画事件中直接绘制传递的画家。相反,创建一个与您的Widget绘图区域大小相同的QImage并在其上绘制。这将使用更快的软件渲染器。然后在需要时将QImage绘制到画家身上。

+0

我们正在使用qt 4.4,我已经尝试先在QPixmap上绘制数据,然后将小部件绘制到小部件上,但加速效果并不理想(QPainter :: drawLine在绘制像素图时并不明显) – smerlin 2011-05-22 18:06:28

+1

我记得QPixmap与QImage的不同之处在于QPixmap使用平台“加速”后端。在OS X中,这意味着它仍然是Core Graphics。使用QImage将确保您使用的是软件渲染器。 – 2011-05-22 20:40:49

+0

@smerlin QPixmap针对在屏幕上显示图像进行了优化,而QImage针对I/O进行了优化。如果你使用QPixmap绘制线条,那么它会变慢。 – Arlen 2011-05-24 04:53:03

0

您可以构建一个QPainterPath并绘制该对象,而不是重复调用drawLine函数。而且,您可以缓存路径,所以在第一次绘制后会更快。

+0

使用QPainterPath的性能差10倍:/ – smerlin 2011-05-23 12:07:04

4

如果你想绘制真的很快,使用OpenGL和QGLWidget

+0

只是从'QGLWidget'而不是'QWidget'派生出来的,因为很多绘画事件都是简单的没有路由到窗口小部件,另外应用程序只是在MacOS上崩溃,并显示错误消息:“必须在QPaintDevice之前构造一个QApplication”,而我显然已经有了一个QApplication实例。 – smerlin 2011-05-23 12:10:39

+0

此外,我怀疑只是切换到OpenGL不会加速任何事情,因为我绘制的数据会改变每一帧,并且这些数据仍然必须上传到显卡几乎每一帧?! – smerlin 2011-05-23 12:18:31

+0

如果您使用QGLWidget,则需要使用OpenGL API绘制图像。在你的照片中绘制简单的折线很容易。是的,当数据每帧改变一次时,数据会被移动到显卡的内存中,但数据量应该非常小,以至于不会成为问题。而实际的绘图将会非常快。 – 2011-05-23 15:55:40