QGraphicsScene缺少一个特定的项目更新 [英] QGraphicsScene is missing a particular item update

查看:376
本文介绍了QGraphicsScene缺少一个特定的项目更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个应用程序,您可以观看给定2D游戏的重放:



基本上,车辆在地图上移动。视图以车辆为中心,所以地图在重放正在播放时正在滚动,微机器 - 类似(这只是给出一个想法,实际的游戏不是微机器 )。





在我的场景中,地图是静态的,而车辆移动。视图是重放的每个帧的滚动,使得车辆居中。
为了性能原因,地图被平铺在几个 QGraphicsPixmapItem 中。



视口更新模式设置到 QGraphicsView :: BoundingRectViewportUpdate
项目索引方法设置为 QGraphicsScene :: NoIndex



在大多数情况下,精细。但是当地图比通常大时,车辆不被更新。视图是滚动和瓷砖很好更新;但不是车辆,除非我通过放大/缩小来触发一个完整的视口更新(所以我知道该项目是定位良好的)。



车辆的boundingRect设置一次并且是有效的(见下面,以逻辑坐标给出)。



调试输出的一些示例(只有第三个配置不起作用):

  ok:
vehicle-> boundingRect():QRectF(-1.9391,-1.9391 3.8782x3.8782)
scene-& QRectF(-117.543,-38.3826 138.834x40.3217)
SCENE_CACHING:85 tiles

ok:
vehicle-> boundingRect():QRectF(-2.88489,-2.88489 5.76979 x5.76979)
scene-> sceneRect():QRectF(-68.8843,-18.2202 187.989x119.277)
SCENE_CACHING:308 tiles

nok: update
vehicle-> boundingRect():QRectF(-3.45546,-3.45546 6.91092x6.91092)
scene-> sceneRect():QRectF(-64.2988,-107.802 188.927x187.445)
SCENE_CACHING:506 tiles

我试图调试更新传递,paint事件确实排除车辆所在的区域...



谁知道更新为什么会错过特定项目?



编辑:



Qt:4.8.1,我已经看到了以前版本的问题

操作系统:Windows XP SP3,尚未在其他操作系统上测试



我没有成功重现问题一个最小的例子。最小的例子只是工作,因为它是预期做的。在现实生活中,这里是做什么:


  1. 从文件读取地图。它由多达数百个定义地面/天空的多边形组成(每个图形由多边形,边和顶点图层组成),数千张照片和纹理,然后剪切到地面或天空,以及其他一些项目。 p>


  2. 我计算所有剪辑,然后在QImage中渲染场景。图像被平铺在几个 QGraphicsPixmapItem 添加到场景,而前面的项目从场景中删除和删除(btw的bug也发生时,我没有删除和删除






这里是一个图形的例子(为了说明这一点)我的意思是地面/天空)。地图可能相当巨大。



解决方案

从上面提取我的评论作为答案:



您需要使用 QGraphicsScene :: invalidate(...)使场景的应重绘的部分无效。


I've got an application where you can watch replays for a given 2D game :

Basically, a vehicle is moving on a map. The view is centered on vehicle so the map is scrolling as replay is playing, something Micro Machines-like (it's just to give an idea, the actual game is not Micro Machines).

In my scene, the map is static while the vehicle is moving around. The view is scrolling for each frame of the replay, so that vehicle is centered. For performance reason, the map is tiled in several QGraphicsPixmapItems.

Viewport update mode is set to QGraphicsView::BoundingRectViewportUpdate. Items index method is set to QGraphicsScene::NoIndex.

In most cases, all is working fine. But when the map is larger than usual, the vehicle is not updated. The view is scrolling and tiles are well updated; but not the vehicle, unless I trigger a full viewport update by zooming in/out (so I know the item is well positioned).

The vehicle's boundingRect is set once for ever, and is valid (see below, given in logical coordinates). I do not paint outside item's bounding rect.

some example of debug output (only third configuration does not work) :

ok :
vehicle->boundingRect() : QRectF(-1.9391,-1.9391 3.8782x3.8782)
scene->sceneRect() : QRectF(-117.543,-38.3826 138.834x40.3217)
SCENE_CACHING : 85 tiles

ok :
vehicle->boundingRect() : QRectF(-2.88489,-2.88489 5.76979x5.76979)
scene->sceneRect() : QRectF(-68.8843,-18.2202 187.989x119.277)
SCENE_CACHING : 308 tiles

nok : vehicle won't update
vehicle->boundingRect() : QRectF(-3.45546,-3.45546 6.91092x6.91092)
scene->sceneRect() : QRectF(-64.2988,-107.802 188.927x187.445)
SCENE_CACHING : 506 tiles

I tried to debug an update pass, and the paint event indeed excludes the region where vehicle is...

Anyone know why an update could miss a particular item ?

Edit :

Qt : 4.8.1, and i've seen the problem with previous versions as well

OS : Windows XP SP3, did not test on other OS yet

I did not succeed in reproducing the problem with a minimal example. The minimal example just work like it is expected to do. In real life, here is what is done :

  1. The map is read from a file. It's composed of up to hundreds of polygons delimiting ground/sky (each one of which is graphically made of polygons, edges and vertices layers), thousands of pictures and textures which are then clipped to ground or sky, and some other items.

  2. I compute all the clippings, and then render the scene in a QImage. The image is tiled in several QGraphicsPixmapItems added to the scene, while the former items are removed from scene and deleted (btw the bug also occured when I didn't remove&delete former items).

  3. The replay is launched

I think Qt Graphics internals are messed up, but I can't figure out how to clean/reset it.

Here is an example of graphics (to illustrate what I mean by ground/sky). The map can be quite huge.

解决方案

Picking up my comment from above as an answer:

You need to use QGraphicsScene::invalidate(...) to invalidate the parts of the scene that should be redrawn.

这篇关于QGraphicsScene缺少一个特定的项目更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆