2

I'm trying to animate the change of a QPixmap, inside QLabel.

I have MainWindow which holds several objects that derive from QScrollArea. Each of these holds a QLabel member.

Using mousePressEvent() I am able to replace the picture of each QLabel using setPixmap(). However, that simply switches the image in each QLabel, while what I would like to achieve is an animation where a new image slides over the existing one.

First I tried using a QTimeLine to draw the QPixmap on the QLabel myself (I've created a class that derives from QLabel for that, and wrote my own setPixmap()) but that didn't work. Next I tried using QPropertyAnimation but it can't construct on a Pixmap without me implementing a sub class for that as well.

Any thoughts or ideas are appreciated.

Triad sou.
  • 2,969
  • 3
  • 23
  • 27

2 Answers2

3

You will need a QObject with a property that can be animated, and generates the intermediate frames for the animation. An incomplete example:

class LabelAnimator : public QObject
{
    Q_OBJECT
    Q_PROPERTY(float progress READ progress WRITE setProgress)
public:
    LabelAnimator(QLabel* label) : mProgress(0.0f), 
                                   mLabel(label), 
                                   mAnimation(new QPropertyAnimation(this, "progress", this) 
    {
        mAnimation->setStartValue(0.0f);
        mAnimation->setEndValue(1.0f);
    }
    void setProgress(float progress) { 
        mProgress = progress;
        QPixmap pix = mOriginalPixmap;
        int offset = - mLabel->width() * (1.0f-progress);
        QPainter painter(&pix);
        painter.paint(off, 0, mNewPixmap);
        painter.end();
        mLabel->setPixmap(pix);
    }
    void setPixmap(const QPixmap& pix) {
        mOriginalPixmap = mLabel->pixmap();
        mNewPixmap = pix;
        mAnimation->start();
    }
};
Dan Milburn
  • 5,600
  • 1
  • 25
  • 18
2

QLabel was never designed for such uses. Draw your QPixmaps inside a QGraphicsView, it is far more focused towards rendering effects and animations.

cmannett85
  • 21,725
  • 8
  • 76
  • 119
  • Hi, sorry for the late response, holidays... I went along with your suggestion and used the graphics view framework. animation seems to work fine now, however there is a little problem. when I add a new pixmapItem to the scene, before I animate it into view, I get this annoying 'flicker', that is, you can see the new pixmap for a (very) short time, then back to the old pixmap, and only then the new pixmap is being animated into the view. any ideas? this happens both with pixmapItems and with textItems. tried to a code snippet but couldn't, I can send anyone interested. thanks. @cbamber85 – Aner Hamama Oct 10 '11 at 23:02
  • Seems the pixmap is being rendered before the QTimeLine is being started. You may have to try experimenting with adding the pixmap to the QGraphicsScene invisible, then starting the QTimeLine, then setting it to visible. It might take a bit of experimenting depending on how Qt uses threading for the QAnimation stuff. – cmannett85 Oct 11 '11 at 06:24