Optimizing Qt 4 Graphics View

During the summer I worked a lot with one of the latest addition to the Qt framework , the graphics view. The graphics view is basically a canvas to draw 2D-graphics, and replaced the QCanvas class from Qt 3.x. It was added to Qt in version 4.2.

The application I worked on is used for displaying a sea map along with various other maritime related information (and a lot of other stuff that’s not really relevant). While the application functioned the way it was, we wanted to replace our old (somewhat hackish) way of representing the parts of the program as CSS-themed top-level widgets and using a embedded graphics view to represent the entire UI of the application. This approach would give us a better ability to integrate the various parts of the application, as well as support transitions between various view states of the program (and other nifty graphics effects). With the recent addition of QGraphicsProxyWidget in Qt 4.4 this was finally an option, so we decided to give it a shot.

During the initial porting of the application, we did not notice much in the way of performance loss, but as soon as we added more (and larger) dynamical elements to the GUI, it started slowing down. This led me to investigate why the application was slowing down, and how to remedy the situation. The reason why is pretty simple: in order for Qt to draw widgets inside the graphics view, it apparently has to render them twice. Qt will first render the widget to an off-screen buffer, and then render the content of the off-screen buffer to the graphics scene as a texture. As soon as we knew why, we started looking at how to optimize it.

Accelerating the Scene:

Qt allows you to use OpenGL to accelerate the scene. This can greatly increase the performance, assuming the graphics card in your computer has decent support for hardware accelerating 2D operations (this is not the case for nVidia today). To enable OpenGL acceleration, you will have to create a QGLWidget and tell the graphics scene to use it as a viewport.  Here’s an example:

QGLWidget* viewport = new QGLWidget(QGLFormat(QGL::DoubleBuffer | QGL::Rgba |
QGL::AlphaChannel | QGL::DirectRendering | QGL::SampleBuffers));
myGraphicsScene->setViewport(viewport);


Item Cache:

The graphics view allows you to independently set the cache mode for each item in the scene.  Setting the cache mode to QGraphicsItem::DeviceCoordinateCache will make Qt use the cached version of a item instead of redrawing the item (twice) every time the scene is updated. This sort of cache will not work if you need to transform (rotate, scale, shear, etc.) the item. If you need transformation you should have a look at the QGraphicsItem::ItemCoordinateCache cache mode.

Increasing the Pixmap Cache Size:

While caching the items works good when you’ve got a small amount of small objects, I soon figured out that when adding larger items, or just a lot of small ones, the drawing becomes slow again. It took me some time, but I finally figured out why. When you tell Qt to use cache for graphics items, it uses its internal QPixmapCache as a buffer for the items. This is not explicitly mentioned in the documentation, only a hint is given in the “See also”-section of the documentation. The default size for this cache is 1024kb , which explains why it gets slower the more items you add. Increasing the cache size is imperative if your application will use a lot of objects and you want cache. You can achieve this by calling the static function QPixmapCache::setCacheLimit(int) , just keep in mind it takes kilobytes as the argument.

Other tricks:

While these tricks are the ones that gave the greatest increase in performance (a dogmatic conclusion, no real benchmarks where made) in our application, there are several other functions you might want to  look at:

QGraphicsView::setOptimizationFlag
QGraphicsView::setViewportUpdateMode
QGraphicsScene::setItemIndexMethod

These functions may give an increase in performance, depending on the nature of the application.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值