9

As the title suggests, I'm looking for a way to color the subpaths of a QPainterPath different colors which is applied to a QGraphicsPathItem, OR simply change the color along the PathItem with a QGradient QPen.

Ultimately I am trying to find the correct solution which will give me the ability to visibly draw a single line, which changes colors based on external variables.

I am using a QGraphicsScene to draw everything.

My current solution has me creating multiple QGraphicsPathItems, each colored differently with their respective QPens. As I get data, I populate the PainterPath associated with those PathItems. This gives me the multicolored lines I need, but the lines are visibly disconnected.

I either need to be able to make subpaths of the QPainterPath invisible during the color change, or alter the gradient applied to a single PathItem. Or maybe there is another approach I am missing. Any help would be wonderful.

-Edit:

This is how I am currently doing the drawing, as noted in the solution to my question. Again, note that I am using a GraphicsScene.

Bearing Formula calculations in GraphicsScene producing erratic results

Here is what I'm trying to do. Desired Result

As you can see the line changes color as it is drawn, by external variables. I'm afraid a Qgradient might not work because the line will not always be straight; the color needs to flow along the line.

Here is what is happening:

enter image description here

As you can see, the red line (PathItem) jumps from where it last was visible to the new position.

To help better clarify the behavior, imagine that this line is being drawn over time. It starts out red, soon a variable gets set and the color of the line segments being drawn change to orange. The red portions of the line remain intact so we can see historically what the state of the variable was at that time. At different times, the variable adjusts and the color applied to new portions of the line update accordingly.

When the line has finished drawing, we can look at it and see when the colors changed.

I hope this all makes sense.

bauervision
  • 847
  • 2
  • 9
  • 25

1 Answers1

6

You can use multiple QPainterPath, one for each color. And then paint them all with the proper color. Be sure to use moveTo() to deplace the current path cursor without drawing a line.

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);

}

render

If you feel the calls to "moveTo" and "lineTo" are a bit heavy, you can encapsulate all the QPainterPaths in you own class with a lineTo(QPointF, QColor) function that will handle the path switching when you change the color.

Benjamin T
  • 8,120
  • 20
  • 37
  • Is this going to work within a GraphicsView / GraphicsScene? I guess it wasn't clear in my question, I will edit it now. This concept is what I'm looking for, as long as I can get it to work with the GraphicsScene. – bauervision Nov 07 '17 at 14:23
  • 1
    @bauervision Yes, GraphicsView / GraphicsScene like widgets use `QPainter`, so the underlying algorithms will be the same. – Benjamin T Nov 07 '17 at 14:34
  • Applying it now, will accept as the correct answer when I get it to work. Standby. When I apply the Path to my PathItem, I assume I just don't apply a QPen? – bauervision Nov 07 '17 at 14:36
  • @bauervision You can either have your own `QGraphicsItem` class and reimplement the `paint()` function. The only change from my code sample is that you have to use the `QPainter *` provided in the function arguments. Or you can have several `QGraphicsPathItem`, each having its own QPainterPath. In the example, I would have 2 items, own for the red and one for the blue. The important part being the use of `moveTo()` to prevent extra lines between sub paths. – Benjamin T Nov 07 '17 at 14:39
  • Yes that is essentially where I'm at with it. If you look at the code provided in the link (the solution) I'm not switching out different paths, but using the same path. Do I need to apply a QPainter if I'm using the QGraphicsPathItem's? My guess is no. – bauervision Nov 07 '17 at 14:44
  • If you use `QGraphicsPathItem`, you only need to call `QGraphicsPathItem::setPath()` . The rest is already cared for. See https://code.woboq.org/qt5/qtbase/src/widgets/graphicsview/qgraphicsitem.cpp.html#_ZN17QGraphicsPathItem5paintEP8QPainterPK24QStyleOptionGraphicsItemP7QWidget – Benjamin T Nov 07 '17 at 14:59
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/158435/discussion-between-bauervision-and-benjamin-t). – bauervision Nov 07 '17 at 16:45