gif image in QLabel
qgraphicsscene, qlabel, qt
Solution
The problem is that `QLabel` has window background by default. You're trying to remove it by do it incorrectly:
`FramelessWindowHint` doesn't make sense here, since it's only used for top level widgets, and a widget added to scene is technically hidden and doesn't have system window frame. This line should be removed.
`setMask` does exactly what you describe it does. Since `QPixmap` is not animated, its mask is the alpha mask of the first frame of animation. And you permanently apply this mask to the label. It's not surpising that it works, but obviously it's not what you want. This line should also be removed.
`setGeometry` line is incorrect. It prevents picture from being visible for me. Label has good size by default and there is no need for `setGeometry`. If you want to scale or move the item on the scene, you can do it after `addWidget` as for any other `QGraphicsItem`. E.g. `addWidget(lbl)->setPos(10, 10)`.
The magic bullet you need is `WA_NoSystemBackground`. It disables background painting for `QLabel` completely. So, the full code would be:
QLabel *lbl = new QLabel;
QMovie *mv = new QMovie("c:/tmp/sun.gif");
mv->start();
lbl->setAttribute(Qt::WA_NoSystemBackground);
lbl->setMovie(mv);
scene.addWidget(lbl);
It works fine for me. However I consider it over-complicated. You should not use proxy widgets in scene unless necessary. You can easily add a movie using `QMovie` and `QGraphicsPixmapItem` and switching pixmaps as movie frames change. I wrote a convenient class for this:
Header:
class GraphicsMovieItem : public QObject, public QGraphicsPixmapItem {
Q_OBJECT
public:
GraphicsMovieItem(QGraphicsItem* parent = 0);
void setMovie(QMovie* movie);
private:
QMovie* m_movie;
private slots:
void frameChanged();
};
Source:
GraphicsMovieItem::GraphicsMovieItem(QGraphicsItem *parent)
: QGraphicsPixmapItem(parent), m_movie(0) {
}
void GraphicsMovieItem::setMovie(QMovie *movie) {
if (m_movie) {
disconnect(m_movie, SIGNAL(frameChanged(int)), this, SLOT(frameChanged()));
}
m_movie = movie;
if (m_movie) {
connect(m_movie, SIGNAL(frameChanged(int)), this, SLOT(frameChanged()));
}
frameChanged();
}
void GraphicsMovieItem::frameChanged() {
if (!m_movie) { return; }
setPixmap(m_movie->currentPixmap());
}
Usage:
QMovie *mv = new QMovie("c:/tmp/sun.gif");
GraphicsMovieItem* item = new GraphicsMovieItem();
item->setMovie(mv);
scene.addItem(item);
Problem
I want to add a gif animated image in QLabel that add into the QGraphicsScene. My code is here: ``` QLabel *lbl = new QLabel; QMovie *mv = new QMovie(":/Images/sun.gif"); mv->start(); lbl->setWindowFlags(Qt::FramelessWindowHint); lbl->setMask((new QPixmap(":/Images/sun.gif"))->mask()); // for create transparent for QLabel image lbl->setMovie(mv); lbl->setGeometry(10,10,10,10); scene.addWidget(lbl); ``` but when I run that it will transparent with first frame of that gif and when the gif is running the photo will not show completely and it will run with transparented area in the first frame. How can I solve that? Thanks