Search code examples
c++qtqgraphicsview

QGraphicsView: Snake-Line and Line animation


I have two questions regarding the QGraphicsView Framework.

The first question is regarding a special line: I wanted to ask whether it is possible to draw an Snake- or Wave-Line (like in the linked image)? I would be grateful for any solution, because I dont have any idea how to get the sinus-shaped line.

Image: a snake line

My second question is about the QGraphicsItemAnimation- I want to animate a QGraphicsLineItem. Right now I am using the method setPosAt() from the QGraphicsItemAnimation. The problem is, that the hole line is moved. My aim is to move only the start or the end point of the QGraphicsLineItem with the QGraphicsItemAnimation. So I want to ask whether this is possible or whether there is any other way to do something like this?

Thanks in advance!

Kind regards - PhiGamma


Solution

  • For the first part of your question : Probably a couple of ways:

    a. Use QPainterPath and the cubicTo() method to create the "path", then use QGraphicsPath with the path you create. In order to do this, you'll need to approximate the sinewave using bezier curves. Some info on that here, and the QPainterPath documentation is here

    b. Subclass QGraphicsItem() and override the paint() event to draw your path using QPainter.

    Sinewave::Sinewave( QGraphicsItem* pParent ) : QGraphicsObject( pParent)
    {
        m_bounds = QRectF(0,0,150,100);
    }
    
    QRectF Sinewave::boundingRect() const
    {
        return m_bounds;
    }
    
    void Sinewave::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
    {
        unsigned int i;
        QPointF last(0,50);
        const int numberOfCycles = 4.0;
        painter->setRenderHint(QPainter::Antialiasing);
    
        for (int i = 0; i < boundingRect().width(); i++)
        {
            double radians = numberOfCycles * 2.0 * PI * static_cast<double>(i) / boundingRect().width();
            double y = sin(radians);
            QPointF next(i, 50 + y*50);
            painter->drawLine(last, next);
            last = next;
        }
    }
    

    Which one you use would depend on what you want the object to do (e.g. do you need to change it's shape at runtime?).

    For your question about animation - no, you can only apply transforms with QGraphcisItemAnimation. I would do it by using a QTimer to drive the change you want in your items in it's timeout() slot.