我想在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运行时,照片将不会完全显示,并且它将在第一帧中以透明区域运行。 我怎么解决这个问题? 感谢
答案 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);
对我来说很好。但我觉得它太复杂了。除非必要,否则不应在场景中使用代理小部件。您可以使用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);