Как по-разному раскрасить подпути QPainterPath?

Как следует из названия, я ищу способ раскрасить подпути QPainterPath разными цветами, которые применяются к QGraphicsPathItem, ИЛИ просто изменить цвет вдоль PathItem с помощью QGradient QPen.

В конечном итоге я пытаюсь найти правильное решение, которое даст мне возможность визуально рисовать одну линию, которая меняет цвет в зависимости от внешних переменных.

Я использую QGraphicsScene для рисования всего.

В моем текущем решении я создал несколько QGraphicsPathItems, каждый из которых окрашен по-разному в соответствии с соответствующими QPens. Когда я получаю данные, я заполняю PainterPath, связанный с этими PathItems. Это дает мне нужные мне разноцветные линии, но линии явно разъединены.

Мне нужно либо сделать подпути QPainterPath невидимыми во время изменения цвета, либо изменить градиент, применяемый к одному PathItem. Или, может быть, есть другой подход, который мне не хватает. Любая помощь будет замечательной.

-Редактировать:

Вот как я сейчас рисую, как указано в решении моего вопроса. Опять же, обратите внимание, что я использую GraphicsScene.

Вычисления формулы подшипника в GraphicsScene дают ошибочные результаты

Вот что я пытаюсь сделать. Желаемый результат

Как вы можете видеть, линия меняет цвет по мере ее рисования внешними переменными. Я боюсь, что Qgradient может не сработать, потому что линия не всегда будет прямой; цвет должен течь вдоль линии.

Вот что происходит:

введите описание изображения здесь

Как видите, красная линия (PathItem) перескакивает с того места, где она была видна в последний раз, на новую позицию.

Чтобы лучше прояснить поведение, представьте, что эта линия рисуется с течением времени. Он начинается красным, вскоре устанавливается переменная, и цвет рисуемых сегментов линии меняется на оранжевый. Красные части линии остаются нетронутыми, поэтому мы можем исторически увидеть, в каком состоянии была переменная в то время. В разное время переменная корректируется, и цвет, применяемый к новым частям линии, соответственно обновляется.

Когда линия закончила рисовать, мы можем посмотреть на нее и увидеть, когда изменились цвета.

Я надеюсь, что все это имеет смысл.


person bauervision    schedule 01.11.2017    source источник
comment
Вы можете показать изображение, что вы получаете и что вы хотите получить, в дополнение к предоставлению минимального, полного и проверяемого примера   -  person eyllanesc    schedule 01.11.2017
comment
Отредактировал мой вопрос   -  person bauervision    schedule 01.11.2017
comment
Вы могли бы показать картину того, что вы получаете, чтобы понять, в чем проблема.   -  person eyllanesc    schedule 01.11.2017
comment
Также покажите свой текущий код, это новый вопрос, и необходимо, чтобы вы предоставили MVCE для этого вопроса.   -  person eyllanesc    schedule 01.11.2017
comment
Это не так просто, я не могу просто вставить сюда свой код. Я буду работать над написанием простой версии, чтобы опубликовать здесь.   -  person bauervision    schedule 01.11.2017
comment
Наиболее целесообразно разместить ту часть, которую вы используете, это основная часть, если у вас есть больше кода, вы можете загрузить его на github, gist или аналогичный и прикрепить ссылку в своем вопросе.   -  person eyllanesc    schedule 01.11.2017
comment
Сейчас работаю над упрощением.   -  person bauervision    schedule 01.11.2017
comment
То, что вы хотите иметь, и то, что вы получаете, имеет разную линию, и это меня смущает. :П   -  person eyllanesc    schedule 01.11.2017
comment
Давайте продолжим обсуждение в чате.   -  person bauervision    schedule 01.11.2017
comment
От чего зависит вариация цветов?   -  person eyllanesc    schedule 06.11.2017
comment
Просто простая переменная int. 1, 2, 3 соответствует каждому из 3 цветов. Устанавливается нажатием кнопки.   -  person bauervision    schedule 06.11.2017
comment
Я не это имел в виду, но это зависит от того, какая часть пути меняет цвет?   -  person eyllanesc    schedule 06.11.2017
comment
Я вижу, что на графике вы хотите, чтобы первые две строки были красными и оранжевыми соответственно, но в третьей до середины строки вы меняете цвета.   -  person eyllanesc    schedule 06.11.2017
comment
По мере изменения этой переменной новые точки, рисуемые на пути, должны отражать новый цвет.   -  person bauervision    schedule 06.11.2017
comment
На этой картинке изменение цвета не имеет ничего общего с изменением угла. Изменение угла осуществляется отдельно. Все изменения цвета зависят от переменной.   -  person bauervision    schedule 06.11.2017
comment
Я полагаю, вы имеете в виду, что как если бы путь был трубкой, а затем она была заполнена 3 жидкостями разных цветов, которые меняются при каждом нажатии кнопки. Я не ошибаюсь?   -  person eyllanesc    schedule 06.11.2017
comment
да. Точно! Извините за путаницу   -  person bauervision    schedule 06.11.2017
comment
Затем вы должны, чтобы цвета менялись в зависимости от времени и того цвета, который изначально имеет путь, если кнопка никогда не нажимается.   -  person eyllanesc    schedule 06.11.2017
comment
По сути, я указал на это в своем последнем редактировании, где я сказал, чтобы помочь лучше прояснить поведение...   -  person bauervision    schedule 06.11.2017


Ответы (1)


Вы можете использовать несколько QPainterPath, по одному для каждого цвета. А потом покрасить их в нужный цвет. Обязательно используйте moveTo(), чтобы сместить текущий курсор пути, не рисуя линию.

void Widget::paintEvent(QPaintEvent *event)
{
    QPainterPath redPath;
    QPainterPath bluePath;
    redPath.moveTo(0,0);
    redPath.lineTo(60,60);
    bluePath.moveTo(60,60);
    bluePath.lineTo(70,20);
    redPath.moveTo(70,20);
    redPath.lineTo(100,100);
    bluePath.moveTo(100,100);
    bluePath.lineTo(160,260);


    QPainter painter(this);
    painter.setRenderHint(QPainter::HighQualityAntialiasing, true);
    painter.setPen(QPen(Qt::red, 4));
    painter.drawPath(redPath);
    painter.setPen(QPen(Qt::blue, 4));
    painter.drawPath(bluePath);

}

рендеринг

Если вы чувствуете, что вызовы «moveTo» и «lineTo» немного тяжеловаты, вы можете инкапсулировать все пути QPainterPath в свой собственный класс с помощью функции lineTo(QPointF, QColor), которая будет обрабатывать переключение пути при изменении цвета.

person Benjamin T    schedule 07.11.2017
comment
Будет ли это работать в GraphicsView / GraphicsScene? Я думаю, что это было неясно в моем вопросе, я отредактирую его сейчас. Эта концепция - то, что я ищу, пока я могу заставить ее работать с GraphicsScene. - person bauervision; 07.11.2017
comment
@bauervision Да, такие виджеты, как GraphicsView / GraphicsScene, используют QPainter, поэтому базовые алгоритмы будут такими же. - person Benjamin T; 07.11.2017
comment
Применив его сейчас, я приму его как правильный ответ, когда он заработает. Поддерживать. Когда я применяю Path к моему PathItem, я предполагаю, что просто не применяю QPen? - person bauervision; 07.11.2017
comment
@bauervision Вы можете либо иметь свой собственный класс QGraphicsItem, либо повторно реализовать функцию paint(). Единственное отличие от моего примера кода заключается в том, что вы должны использовать QPainter *, указанные в аргументах функции. Или у вас может быть несколько QGraphicsPathItem, каждый из которых имеет свой QPainterPath. В примере у меня было бы 2 предмета, собственный для красного и один для синего. Важной частью является использование moveTo() для предотвращения лишних строк между подпутями. - person Benjamin T; 07.11.2017
comment
Да, это, по сути, то, где я нахожусь с этим. Если вы посмотрите на код, указанный в ссылке (решение), я не переключаю разные пути, а использую один и тот же путь. Нужно ли применять QPainter, если я использую QGraphicsPathItem? Я предполагаю, что нет. - person bauervision; 07.11.2017
comment
Если вы используете QGraphicsPathItem, вам нужно вызвать только QGraphicsPathItem::setPath(). Об остальном уже позаботились. См. code.woboq.org/qt5/qtbase /src/widgets/graphicsview/ - person Benjamin T; 07.11.2017
comment
Давайте продолжим обсуждение в чате. - person bauervision; 07.11.2017