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?


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.