PDA

View Full Version : QGraphicsItem flickering



michalk
14th May 2011, 12:42
I have following problem:
I have a BallItem class derived from QGraphicsItem.
When I update position of my BallItem, Ballitem is flickering and sometimes in the screen (QGraphicsView) there are some remains left.

I attach source code of overrode methods:



BallItem::BallItem(qreal aPosX, qreal aPosY, qreal aRadius,QGraphicsItem *aParent) :
QGraphicsItem(aParent),
iVx(0),iVy(0),iRadius(aRadius)
{
setPos(aPosX,aPosY);
}


QRectF BallItem::boundingRect() const
{
qreal adjust = 0.5;
QRectF rectf = QRectF(-iRadius-adjust,-iRadius-adjust,iRadius*2 + adjust
,iRadius*2 + adjust);
return rectf;
}


void BallItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
QWidget *widget)
{
painter->save();

painter->setBrush(Qt::red);
painter->drawEllipse(QPointF(0,0),iRadius,iRadius);

painter->restore();
}


Here I initialise QGraphicsView (iGameView) and QGraphicsScene (iGameScene)



iGameView->setRenderHint(QPainter::Antialiasing);
iGameView->setCacheMode(QGraphicsView::CacheBackground);
iGameView->setViewportUpdateMode(QGraphicsView::BoundingRectV iewportUpdate);
iGameView->setBackgroundBrush(Qt::green);
iGameView->setAttribute(Qt::WA_LockPortraitOrientation, true);

iGameScene->setItemIndexMethod(QGraphicsScene::NoIndex);

iGameView->setScene(iGameScene);


I make position updates in advance method.


void BallItem::advance(int phase)
{
if (!phase)
return;

bool flipX = false;
bool flipY = false;

qreal newX = x();
qreal newY = y();

if (newX + iRadius + iVx > scene()->width())
{
newX = scene()->width() - iRadius;
flipX = true;
}
else if (newX - iRadius +iVx < 0)
{
newX = iRadius;
flipX = true;
}
else
newX+=iVx;

if (newY + iRadius + iVy > scene()->height())
{
newY = scene()->height() - iRadius;
flipY = true;
}
else if (newY - iRadius + iVy < 0)
{
newY = iRadius;
flipY = true;
}
else
newY+=iVy;

setPos(newX,newY);

if (flipX)
iVx = -iVx;

if (flipY)
iVy = -iVy;

}


I am sorry for attaching so much source code but I know that there are some issues about mapping from item coordinate system to scene coordinate system and maybe I do something wrong in presented source code. Something what will be caught by more experienced eye.

wysota
17th May 2011, 01:20
You are drawing outside your boundingRect(). Calling setPos() in the item constructor doesn't make much sense either.

michalk
17th May 2011, 09:18
Do you mean adding adjust*2 when I specify rectf width and height?



QRectF BallItem::boundingRect() const
{
qreal adjust = 0.5;
QRectF rectf = QRectF(-iRadius-adjust, -iRadius-adjust, iRadius*2 + adjust*2
, iRadius*2 + adjust*2);

return rectf;
}

wysota
17th May 2011, 10:36
Simplify the code (QRectF has a bunch of nice methods). And what's the purpose of calling setPos() in the constructor?

michalk
17th May 2011, 13:05
I am going to rewrite it so it will look better.

If it comes to constructor, hmm well it is a remaining from my try-outs, setPos() is going to be removed. Now I know it is not the best way to do so, but when I started with QGraphics... stuff I didn't know that.