Text animations



  • Hi there,

    I need to implement a feature in my application that shows music lyrics in real time, just like SingStar.
    I've been thinking of using QGraphicsView/Scene to do this, and QGraphicsItemAnimation to make the lyrics interactive scaling them up and down as the lyrics pass by.
    I'm having a hard time making the scaling animations to work from the center of the QGraphicsTextItems... The scaling is made from the left upper corner of the item bounding rectangle... Is it possible to make it work from the center?

    Thank you very much.



  • @yourTextItem->setTransformOriginPoint(p);@
    where p is a QPointF in the center of the text item (in the reference frame of the text item). You could either determine p yourself via QFontMetrics or just use the width and height divided by two of yourTextItem->boundingRect(), right after you've create the item and applied the text.



  • I've tried that already but it doesn't work from the center...

    "I'm posting my code:":https://feupload.fe.up.pt/get/FCFkNIsPhdQQETg



  • Indeed, setTransformOriginPoint seems to only work for setRotation and setScale, not for rotate() and scale() (which are obviously used by the QGraphicsItemAnimation framework).

    Well so let's just create a parent object in which the text is positioned centered, and rotate that parent object instead, like this:
    @
    #include "textanimation.h"

    textanimation::textanimation(QWidget *parent, Qt::WFlags flags)
    : QMainWindow(parent, flags)
    {
    ui.setupUi(this);

    scene = new QGraphicsScene;
    ui.graphicsView->setScene(scene);

    node = new QGraphicsItemGroup;
    scene->addItem(node);
    textItem = scene->addSimpleText("Press mouse left button!", QFont("Arial", 24));
    textItem->setParentItem(node);
    textItem->setPos(-textItem->boundingRect().center());
    textItem->setBrush(QBrush(QColor(Qt::green)));
    textItem->setPen(QPen(QColor(Qt::blue), 2));

    timer = new QTimeLine(1000);
    timer->setFrameRange(0, 100);
    timer->setEasingCurve(QEasingCurve::OutInSine);

    animation = new QGraphicsItemAnimation;
    animation->setItem(node);
    animation->setTimeLine(timer);

    animation->setScaleAt(0.0, 1, 1);
    animation->setScaleAt(0.5, 1.5, 1.5);
    animation->setScaleAt(1.0, 1, 1);
    }

    textanimation::~textanimation()
    {
    delete scene;
    delete timer;
    delete animation;
    }

    void textanimation::mousePressEvent(QMouseEvent *e)
    {
    if(e->isAccepted())
    if(e->button() == Qt::LeftButton)
    timer->start();
    }

    void textanimation::showEvent(QShowEvent*)
    {
    node->setPos(ui.graphicsView->width()/2, ui.graphicsView->height()/2);
    ui.graphicsView->setSceneRect(0, 0, ui.graphicsView->width()-2, ui.graphicsView->height()-2);
    }

    void textanimation::resizeEvent(QResizeEvent*)
    {
    node->setPos(ui.graphicsView->width()/2, ui.graphicsView->height()/2);
    ui.graphicsView->setSceneRect(0, 0, ui.graphicsView->width()-2, ui.graphicsView->height()-2);
    }
    @

    node is defined as private member of textanimation in textanimation.h:
    QGraphicsItemGroup *node;

    I've cleaned up your animation code. There's no need to set every single frame, you just set keyframes and the rest gets interpolated. here I use the OutInSine interpolation to make the animation between the keyframes smooth.



  • It works great. Thank you very much for your help! :)
    I wasn't aware of the interpolation.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.