Как заполнить QPainterPath

229
08 февраля 2019, 03:50

Не понимаю как использовать void QPainterPath::setFillRule(Qt::FillRule fillRule).

У меня с помощью ф-ции pathBezierCurve() создается объект типа QPainterPath. На картинке ниже он обведен в красные рамки. Эти пути пересекаются, и на пересечении (провел желтые полоски) объект сцены не выделяется. Как исправить?
Пример кода ниже. Весь проект на гитхаб.

У меня такой код:

QPainterPath Edge::pathBezierCurve() const {    // + text
    QPainterPath path;
    qreal qOffset = 5;
    QPointF newBezier = newPosBezier();
    QLineF line0(mapFromScene(source->pos()), newBezier);
    QLineF line1(newBezier, mapFromScene(dest->pos()));
    qreal dx0 = qOffset * sin(line0.angle() * M_PI / 180);
    qreal dy0 = qOffset * cos(line0.angle() * M_PI / 180);
    qreal dx1 = qOffset * sin(line1.angle() * M_PI / 180);
    qreal dy1 = qOffset * cos(line1.angle() * M_PI / 180);
    QPointF offset0(dx0, dy0);
    QPointF offset1(dx1, dy1);
    path.moveTo(mapFromScene(source->pos() + offset0));
    path.cubicTo(newBezier + (offset0 + offset1) / 2,
                 newBezier + (offset0 + offset1) / 2,
                 mapFromScene(dest->pos()) + offset1);
    path.lineTo(mapFromScene(dest->pos()) - offset1);
    path.cubicTo(newBezier - (offset0 + offset1) / 2,
                 newBezier - (offset0 + offset1) / 2,
                 mapFromScene(source->pos()) - offset0);
    path.lineTo(mapFromScene(source->pos()) + offset0);
    // Text
    QPointF textPoint = newPosText();
    qreal x = textPoint.x();
    qreal y = textPoint.y();
    path.moveTo(x, y);
    path.lineTo(x, y - 18); // for QFont("Times", 11)
    path.lineTo(x + 8 * textEdge.size(), y - 18);
    path.lineTo(x + 8 * textEdge.size(), y + 4);
    path.lineTo(x, y + 4);
    path.lineTo(x, y);
    return path;
}
// Для столкновений и выделения
QPainterPath Edge::shape() const {
    QPainterPath path;
    path = pathBezierCurve();
    return path;
}
// parent class
void NodeEdgeParent::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QPen pen(Qt::red, 0, Qt::SolidLine);
    painter->strokePath(shape(), pen);
}

может кто помочь?

Answer 1

setFillRule() работает при объединении с помощью united().

QPainterPath Edge::pathText() const {
    QPainterPath path;
    QPointF textPoint = posText();
    qreal x = textPoint.x();
    qreal y = textPoint.y();
    path.moveTo(x, y);
    path.lineTo(x, y - 18); // for QFont("Times", 11)
    path.lineTo(x + 8 * _textContent.size(), y - 18);
    path.lineTo(x + 8 * _textContent.size(), y + 4);
    path.lineTo(x, y + 4);
    path.lineTo(x, y);
    return path;
}
QPainterPath Edge::pathBezierCurve() const {
    QPainterPath path; // тут не нужно path.setFillRule(Qt::WindingFill);
    qreal qOffset = 5;
    QPointF newBezier = newPosBezier();
    QLineF line0(mapFromScene(source->pos()), newBezier);
    QLineF line1(newBezier, mapFromScene(dest->pos()));
    qreal dx0 = qOffset * sin(line0.angle() * M_PI / 180);
    qreal dy0 = qOffset * cos(line0.angle() * M_PI / 180);
    qreal dx1 = qOffset * sin(line1.angle() * M_PI / 180);
    qreal dy1 = qOffset * cos(line1.angle() * M_PI / 180);
    QPointF offset0(dx0, dy0);
    QPointF offset1(dx1, dy1);
    path.moveTo(mapFromScene(source->pos() + offset0));
    path.cubicTo(newBezier + (offset0 + offset1) / 2,
                 newBezier + (offset0 + offset1) / 2,
                 mapFromScene(dest->pos()) + offset1);
    path.lineTo(mapFromScene(dest->pos()) - offset1);
    path.cubicTo(newBezier - (offset0 + offset1) / 2,
                 newBezier - (offset0 + offset1) / 2,
                 mapFromScene(source->pos()) - offset0);
    path.lineTo(mapFromScene(source->pos()) + offset0);
    return path;
}
// Для столкновений и выделения
QPainterPath Edge::shape() const {
    QPainterPath path;
    path.setFillRule(Qt::WindingFill);
    // setFillRule работает при объединении с помощью united
    path = pathBezierCurve().united(pathText());
    return path;
}

READ ALSO
Как создать один массив из двух

Как создать один массив из двух

Заданы массивы А (n) и В (m)Сформировать массив С (n + m), элементами которого являются n элементов массива A, за которыми следуют m элементов массива...

236
Пополнение баланса номера через API WebMoney

Пополнение баланса номера через API WebMoney

WebMoney предоставляет множество интерфейсов для разработчиковНо, к сожалению, я не смог найти подходящий мне

250
Неправильная генерация сертификата X.509

Неправильная генерация сертификата X.509

В проекте используется ЭП для подписания некоторых данных на формеПри тестировании локально на своем ПК (Windows) все происходит идеально: юзер...

250
Как в метод передать ссылку на объект?

Как в метод передать ссылку на объект?

У меня есть методЯ передаю в него название нового объекта data и его будущий номер num

402