QGraphicsItem leaves artifacts when changing boundingRect
Asked Answered
I

1

6

My LineItem inheriting from QGraphicsLineItem can change its pen width.

I have created a boundingRect that uses the QGraphicsLineItem::boundingRect adjusted by pads that get calculated based on pen width and arrows. It works.

void LineItem::calculateStuff() // called on any change including pen width
{
    qreal padLeft, padRight, padT;
    padLeft = 0.5 * m_pen.width();  // if no arrows
    padT = padLeft;
    padRight = padLeft;
    m_boundingRect = QGraphicsLineItem::boundingRect().adjusted(-padLeft, -padT, padRight, padT);
    update();
}
QRectF LineItem::boundingRect() const
{
    return m_boundingRect;
}
QPainterPath LineItem::shape() const
{
    QPainterPath p;
    p.addRect(m_boundingRect);
    return p;
}

There is only one artifact that I get:

  • if I increase the pen width, then decrease it, I get traces:

enter image description here enter image description here

  • these of course disappear as soon as i move mouse or any action (I had a hard time getting the screen shots)

As pretty as they are (seriously I consider them a "feature :-) ) - I am trying to eliminate them. I tried to remember previous bounding rectangle, and update the item with the previous bounding rectangle - i thought that was what the option was for - but it didn't work.

QRectF oldRect = selectedItem->boundingRect();
item->setItemPenWidth(p);
selectedItem->update(oldRect);
selectedItem->update();

My viewport has

setViewportUpdateMode(BoundingRectViewportUpdate);

If I change to

setViewportUpdateMode(FullViewportUpdate);

I don't get artifacts - but I think this will impact performance which is a major constraint.

How can I fix these artifacts - that only occur in that specific situation, decreasing pen width / decreasing bounding rect of line, without impacting performance ?

Ichneumon answered 14/8, 2015 at 14:58 Comment(0)
I
5

Simple fix... I had to add

prepareGeometryChange();

in my calculateStuff() function.

I have not seen any changes from this before, it is the first time I change my boundingRect that it does not update seamlessly.

Ichneumon answered 14/8, 2015 at 15:31 Comment(2)
Changing the bounding rectangle before calling prepareGeometryChange is undefined behavior. Sure you might not have seen ill effects before: that's what undefined behavior is. Be thankful it didn't format your hard drive (undefined behavior can lead to that, by its very nature).Peregrination
@KubaOber I think it did... that one time ... :-)... so I would have to call it every time before changing the boundingRect, for every property... When I said I did not see changes, I include the fact that, even without this call, resizing the line or adding arrows actually leaves no artifacts, which was puzzling.Ichneumon

© 2022 - 2024 — McMap. All rights reserved.