Dave Mateer
Dave Mateer

Reputation: 17956

QPainterPath grow / expand

Is there any way to take a QPainterPath and expand it, like the Selection > Grow... (or Expand...) command in Photoshop?

I want to take the QPainterPath returned from QGraphicsItem::shape and use that as the basis for a QGraphicsPathItem. But I want to expand the shape by a given amount, say 10 pixels all around. And then draw a thin outline around this expanded shape.

I can kind of do this by setting the width of the QPen used to draw the QGraphicsPathItem to 20 (my desired width * 2 because it draws half inside and half outside). That gives the right outside shape, but with an ugly thick line; there is no way (that I can see) to get this shape and outline it with a thin line.

The QPainterPathStroker class looks promising, but I can't seem to get it do to what I want to.

Upvotes: 4

Views: 3867

Answers (2)

Marc Mutz - mmutz
Marc Mutz - mmutz

Reputation: 25353

To grow a QPainterPath by x pixels, you could use a QPainterPathStroker with a 2*x wide pen, then unite the original with the stroked path:

QPainterPath grow( const QPainterPath & pp, int amount ) {
    QPainterPathStroker stroker;
    stroker.setWidth( 2 * amount );
    const QPainterPath stroked = stroker.createStroke( pp );
    return stroked.united( pp );
}

Note, however, that since Qt 4.7, the united() function (and similar set operations) turn the paths into polylines to work around a numerical instability in the path intersection code. While this is fine for drawing (there shouldn't be any visible difference between the two methods), if you intend to keep the QPainterPath around, e.g. to allow further operations on it (you mentioned Photoshop), then this will destroy all bezier curves in it, which is probably not what you wanted.

Upvotes: 6

Stephen Chu
Stephen Chu

Reputation: 12832

QPainterPathStroker is the right idea:

QPainterPathStroker stroker;
stroker.setWidth(20);
stroker.setJoinStyle(Qt::MiterJoin); // and other adjustments you need
QPainterPath newpath = (stroker.createStroke(oldPath) + oldPath).simplified();

QPainterPath::operator+() unites 2 paths and simplified() merges sub-paths. This will also handle "hollowed" paths.

Upvotes: 5

Related Questions