GIF-изображение в QLabel
Я хочу добавить анимированное изображение GIF в QLabel, которое добавляется в QGraphicsScene. Мой код здесь:
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);
но когда я запускаю его, он будет прозрачным с первым кадром этого gif-файла, а когда gif-файл запущен, фотография не будет отображаться полностью и будет работать с прозрачной областью в первом кадре. Как я могу решить это? Спасибо
1 ответ
Проблема в том, что QLabel
по умолчанию имеет фон окна. Вы пытаетесь удалить это, сделав это неправильно:
FramelessWindowHint
здесь не имеет смысла, поскольку он используется только для виджетов верхнего уровня, а виджет, добавленный в сцену, технически скрыт и не имеет системной рамки окна. Эта строка должна быть удалена.
setMask
делает именно то, что вы описываете, это делает. поскольку QPixmap
не анимирован, его маска является альфа-маской первого кадра анимации. И вы навсегда наносите эту маску на этикетку. Это не удивительно, что это работает, но, очевидно, это не то, что вы хотите. Эта строка также должна быть удалена.
setGeometry
линия неверна. Это препятствует тому, чтобы картина была видимой для меня. Этикетка имеет хороший размер по умолчанию и нет необходимости setGeometry
, Если вы хотите масштабировать или перемещать объект на сцене, вы можете сделать это после addWidget
как и для любого другого QGraphicsItem
, Например addWidget(lbl)->setPos(10, 10)
,
Волшебная пуля вам нужна WA_NoSystemBackground
, Отключает рисование фона для QLabel
полностью. Итак, полный код будет:
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);
Он отлично работает для меня. Однако я считаю это слишком сложным. Вы не должны использовать прокси-виджеты в сцене без необходимости. Вы можете легко добавить фильм, используя QMovie
а также QGraphicsPixmapItem
и переключение растровых изображений при смене кадров фильма. Я написал удобный класс для этого:
Заголовок:
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();
};
Источник:
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());
}
Использование:
QMovie *mv = new QMovie("c:/tmp/sun.gif");
GraphicsMovieItem* item = new GraphicsMovieItem();
item->setMovie(mv);
scene.addItem(item);