需要关于Qt绘画的性能改进建议

时间:2017-11-05 03:48:19

标签: multithreading qt qpixmap

为简单起见,我的应用程序有两个滚动条。当任何滚动条改变时,QPainter重新绘制图像。

代码

  // connect valueChanged to update
  connect(this->horizontalScrollBar(),
      SIGNAL(valueChanged(int)),
      this,
      SLOT(UpdateVisibleArea()));

  connect(this->verticalScrollBar(),
      SIGNAL(valueChanged(int)),
      this,
      SLOT(UpdateVisibleArea()));
在UpdateVisibleArea()中,调用QWidget.update()方法。并且QWidget.paintEvent()方法的实现方式如下:

QPixmap q_pixmap;
if (!ImageCache::GetPixmap(cache_key, &q_pixmap)) {
    // there're up to thousands of images, we can not pre-load them all into the cache.
    // the following statement may take 80~250ms.
    loadImage(cache_key, &q_pixmap);    
    ImageCache::PutPixmap(cache_key, q_pixmap);
}

QPainter q_painter;
q_painter.drawPixmap(...);  // usually it takes less than 20ms.

问题

当我快速拖动滚动条时,感觉非常迟钝。

我的想法

  1. 图像应以后台线程加载。但问题是,qpainter实例正在等待UI线程。图像未准备就绪时无法继续。
  2. 当滚动条快速变化时,有没有办法阻止重新发生这么快?
  3. 我的问题

    您能否告诉我一些如何优化它的线索?

1 个答案:

答案 0 :(得分:0)

  

如何针对滚动的多个对象优化复杂绘图   内容?

当我们在屏幕上实际绘制图形缓冲区之前填充图形缓冲区时,可以通过“屏幕外渲染”来完成。在滚动的情况下,我们可以将整个滚动内容预填充为一个大的矩形区域,或者我们可以使用足够大的矩形“窗口”,以便我们更容易滚动。我们应该使用较小的滚动窗口缓冲区,而不是整个滚动矩形用于屏幕外渲染取决于滚动内容的大小。

使用OpenGL和帧缓冲可以进一步改进这种技术。这可以使用QOpenGLWidget或使用QML QQuickPaintedItem(这意味着整个UI是QML)。第二个例子没有详细说明屏幕外缓冲技术,但只是展示了在QML中使用framebuffer。第一个例子中的相同技术可以在那里进行一些改变。