问题在于
QLabel
默认具有窗口背景。您试图通过不正确的方式来删除它:
FramelessWindowHint
在这里没有意义,因为它仅用于顶级小部件,并且添加到场景中的小部件在技术上是隐藏的,没有系统窗口框架。应该删除此行。
setMask
正好做了您所描述的操作。由于QPixmap
不是动画的,其掩码是动画的第一帧的Alpha掩码。而且您永久地将此掩码应用于标签。这似乎能够正常工作,但显然不是您想要的。也应该删除此行。
setGeometry
的代码行是不正确的。对我而言,它会阻止图片的可见性。默认情况下,标签的大小很好,不需要使用setGeometry
。如果您想要缩放或移动场景上的项目,则可以像其他任何QGraphicsItem
一样在addWidget
之后进行操作。例如: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);