Как сделать boundingRect () в форме дуги?

Мой класс наследует от QGraphicsItem. Я рисую его с painter — >drawArc, и я хочу сделать ту же границу для этого объекта, но QpainterPath не имеет такой функции, как painter. arcTo это не то же самое, потому что он имеет линию от центра.

Код (Width-ширина пера, поэтому столкновение происходит на внешней границе дуги.):

QRectF Circle::boundingRect() const
{
    QRectF rect( -radius, -radius, radius*2, radius*2);
    return rect;
}

QPainterPath Circle::shape() const
{
    QPainterPath path;
    path.arcTo(-radius-width, -radius-width, (radius+width)*2, (radius+width)*2, startAngle/16, spanAngle/16);
    return path;
}

void Circle::paint(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QPen pen;
    pen.setCapStyle(Qt::FlatCap);
    pen.setWidth(width);
    painter->setPen(pen);
    painter->drawArc(boundingRect(), startAngle, spanAngle);

}

1 ответ

  1. Вы должны использоватьQPaintePath::arcTo, но вы должны переместить текущую позицию в начальную точку дуги, иначе дуга будет соединена с текущей позицией линией.

    Для перемещения текущей позиции в начальной точке можно использовать QPaintePath::arcMoveTo

    Образец

    QPainterPath pp;
    pp.arcMoveTo(rect, startAngle);
    pp.arcTo(rect, startAngle, spanAngle);
    

    Рассмотрите также возможность использования QPainterPathStrokerдля придания формы толщины. А также добавьте ширину пера в ограничивающую прямую

    Образец:

    QRectF Circle::boundingRect() const
    {
        return QRectF(-radius - width, -radius - width, (radius + width) * 2, (radius + width) * 2);
    }
    
    QPainterPath Circle::shape() const
    {
        QRectF rect(-radius, -radius, radius * 2, radius * 2);
        QPainterPath path;
        path.arcMoveTo(rect, startAngle / 16);
        path.arcTo(rect, startAngle / 16, spanAngle / 16);
        QPainterPathStroker pps;
        pps.setCapStyle(Qt::FlatCap);
        pps.setWidth(width);
        return pps.makeStroke(path);
    }
    
    void Circle::paint(QPainter * painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        QPen pen;
        pen.setCapStyle(Qt::FlatCap);
        pen.setWidth(width);
        painter->setPen(pen);
        QRectF rect(-radius, -radius, radius * 2, radius * 2);
        painter->drawArc(rect, startAngle, spanAngle);
    
    }