How to animate QWidget’s background using a GIF

How to animate QWidget’s background using a GIF

If you’ve ever used QLabel, you might’ve come across one of its methods: QLabel::setMovie, which is very useful for animating its background.

Unfortunately, QWidget does not provide such a method. A limitation that I came across and couldn’t find a solution about it. So I came up with my own solution and felt the need to share it.

Tools:

Implementation:

QMovie could be used by connecting its frameChanged slot to a function that sets QWidget’s palette brush to each frame.

Reimplement:

Custom QWidget Class:

class MAnimatedBackground : public QWidget
{
    Q_OBJECT

public:
    QMovie *movie = new QMovie(":/GIFBackground.gif");
    QPalette customPalette;
    MAnimatedBackground(QWidget *parent = nullptr)
    {
        //resize the gif to the widget's size
        movie->setScaledSize(size());
        //I'm using a looping gif and cashing reduced cpu consumption
        movie->setCacheMode(QMovie::CacheAll);

        //I used a lambda that gets the current frame as a QPixmap
        //and used it as the widget palette brush with the window flag
        QTimer::connect(movie,&QMovie::frameChanged,[=]()
        {
            customPalette = palette();
            customPalette.setBrush(QPalette::Window, movie->currentPixmap());
            setPalette(customPalette);
        });
    }

protected:
    void resizeEvent(QResizeEvent *event) 
    {
        //rescale the gif every time the widget resizes
        movie->setScaledSize(size());
    }
    void showEvent(QShowEvent *event) 
    {
        //start/resume the movie only when the widget is about to show
        movie->start();
    }
    void hideEvent(QHideEvent *event) 
    {
        //pause the movie when the widget hides
        movie->setPaused(true);
    }
};

Result:

The custom widget with a GIF as background

Since QWidget is the most basic widget in Qt Framework — meaning every Qt widget inherits from it — , this could be applied and tweaked in so many ways.

Feel free to suggest improvements and share your thoughts and feedback!