QLabel中的gif图像

时间:2014-07-06 05:14:14

标签: qt qgraphicsscene qlabel

我想在QLabel中添加一个添加到QGraphicsScene中的gif动画图像。 我的代码在这里:

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 个答案:

答案 0 :(得分:6)

问题是QLabel默认具有窗口背景。你试图通过错误地删除它来删除它:

FramelessWindowHint在这里没有意义,因为它仅用于顶级小部件,并且添加到场景的小部件在技术上是隐藏的,并且没有系统窗口框架。该行应删除。

setMask正是您所描述的。由于QPixmap未设置动画,因此其蒙版是第一帧动画的alpha蒙版。并且您将此蒙版永久应用于标签。它的工作原理并不令人惊讶,但显然这不是你想要的。此行也应删除。

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);

对我来说很好。但我觉得它太复杂了。除非必要,否则不应在场景中使用代理小部件。您可以使用QMovieQGraphicsPixmapItem轻松添加电影,并在电影帧发生变化时切换像素图。我为此写了一个方便的课程:

部首:

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);