Position label on a QPainterPath curve
-
I'm trying to create a QGraphicsItem representing a labeled curve. The part of the curve where the label is placed should not be drawn.
I tried to achieve this by setting a dash pattern for the pen. Here's an example of a line with a gap in the middle:
@
class MyPath : public QGraphicsItem
{
public:
MyPath()
: penWidth(5)
{
path.moveTo(QPointF(-500, 0));
path.lineTo(QPointF( 500, 0));
}QRectF boundingRect() const
{
return path.boundingRect().adjusted(penWidth/2, penWidth/2, penWidth/2, penWidth/2);
}void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
qreal length = path.length() / penWidth;QPen pen(Qt::SolidPattern, penWidth); pen.setDashPattern(QVector<qreal>() << length/2 - 5*penWidth << 10*penWidth << length/2 - 5*penWidth << 0); painter->setPen(pen); painter->drawPath(path);
}
private:
QPainterPath path;
qreal penWidth;
};
@This seems to do what I want at the first glance. Here's a minimal working example:
@
int main(int argc, char *argv[])
{
QApplication app(argc, argv);QGraphicsScene *scene = new QGraphicsScene;
scene->addItem(new MyPath);QGraphicsView *view = new QGraphicsView(scene);
qreal scaleFactor = 1;
view->setTransform(QTransform::fromScale(scaleFactor, scaleFactor));view->show();
return app.exec();
}
@However setting scaleFactor to a small value (e.g. scaleFactor = 0.15) results in a line where the gap is no longer in the middle.
I don't know what causes this problem. Here's a workaround (which doesn't draw the curve but rather draws the interior of its outline):
@
class MyPath : public QGraphicsItem
{
public:
MyPath()
: penWidth(5)
{
path.moveTo(QPointF(-500, 0));
path.lineTo(QPointF( 500, 0));qreal length = path.length() / penWidth; QPainterPathStroker stroker; stroker.setWidth(penWidth); stroker.setDashPattern(QVector<qreal>() << length/2 - 5*penWidth << 10*penWidth << length/2 - 5*penWidth << 0); path = stroker.createStroke(path);
}
QRectF boundingRect() const
{
return path.boundingRect().adjusted(penWidth/2, penWidth/2, penWidth/2, penWidth/2);
}void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::SolidPattern);painter->drawPath(path);
}
private:
QPainterPath path;
qreal penWidth;
};
@What is the problem with my first attempt?
And is there maybe even a better way to draw only part of a QPainterPath?