我使用Qt QMovie播放GIF集合。在到达GIF的最后一帧时,我断开信号,停止QMovie并启动下一个QMovie。在此步骤之前,代码工作正常。
在此之后,我将介绍可以在GIF中导航的下一个和上一个按钮。这些按钮的onClick操作执行与上面相同的操作,除了不等待最后一帧,我立即断开连接并停止电影。
这会随机导致所有GIF播放速度超过正常速度。而且,即使在帧结束之前,即将到来的GIF也会突然导航到下一个GIF。
此效果会以指数方式消耗大量内存。终于崩溃了应用程序。
这是我的头文件
class AnimationBox : public QWidget
{
Q_OBJECT
public:
explicit AnimationBox(QWidget *parent = 0);
~AnimationBox();
private slots:
void loopAnimation(int frame);
void changeSlide(int direction = 1);
void prevGIFSlot();
void nextGIFSlot();
private:
Ui::AnimationBox *ui;
std::vector<QMovie*> movieVector;
int currentMovieIndex;
};
这是我的cpp文件
AnimationBox::AnimationBox(QWidget *parent)
: QWidget(parent)
, ui(new Ui::AnimationBox),
{
ui->setupUi(this);
currentMovieIndex = 0;
movieVector.push_back(new QMovie("/Users/qq/Desktop/gif1.gif"));
movieVector.push_back(new QMovie("/Users/qq/Desktop/gif2.gif"));
movieVector.push_back(new QMovie("/Users/qq/Desktop/gif3.gif"));
ui->movieLabel->setMovie(movieVector[currentMovieIndex]);
movieVector[currentMovieIndex]->start();
connect(movieVector[currentMovieIndex], SIGNAL(frameChanged(int)), this, SLOT(loopAnimation(int)));
connect(ui->leftButton, SIGNAL(clicked()), this, SLOT(prevGIFSlot()));
connect(ui->rightButton, SIGNAL(clicked()), this, SLOT(nextGIFSlot()));
}
void AnimationBox::loopAnimation(int frame)
{
if (frame == movieVector[currentMovieIndex]->frameCount() - 1)
{
disconnect(movieVector[currentMovieIndex], SIGNAL(frameChanged(int)), this, SLOT(loopAnimation(int)));
movieVector[currentMovieIndex]->stop();
changeSlide();
}
}
void AnimationBox::prevGIFSlot()
{
disconnect(movieVector[currentMovieIndex], SIGNAL(frameChanged(int)), this, SLOT(loopAnimation(int)));
movieVector[currentMovieIndex]->stop();
changeSlide(-1);
}
void AnimationBox::nextGIFSlot()
{
disconnect(movieVector[currentMovieIndex], SIGNAL(frameChanged(int)), this, SLOT(loopAnimation(int)));
movieVector[currentMovieIndex]->stop();
changeSlide(1);
}
void AnimationBox::changeSlide(int direction)
{
currentMovieIndex = (currentMovieIndex + direction) % movieVector.size();
ui->movieLabel->setMovie(movieVector[currentMovieIndex]);
movieVector[currentMovieIndex]->start();
connect(movieVector[currentMovieIndex], SIGNAL(frameChanged(int)), this, SLOT(loopAnimation(int)));
}
答案 0 :(得分:0)
此外,即将到来的GIF也会突然导航到下一个GIF 在到达帧结束之前。
这是因为在加载最后一帧时调用了一个插槽loopAnimation(int frame)
,并且您的插槽会停止播放电影.. 在播放帧本身之前足够早,因此它会被切断...
这个微小的变化向您展示了如何避免这种情况:
void AnimationBox::loopAnimation(int frame)
{
if (frame == 0)
{
disconnect(movieVector[currentMovieIndex], SIGNAL(frameChanged(int)), this, SLOT(loopAnimation(int)));
movieVector[currentMovieIndex]->stop();
changeSlide();
}
}
请注意,这是一个条件解决方案,因为您实际上在连接到插槽之前启动了电影..所以当帧最初为0时它不会被击中,但它会在下一个动画周期被击中,但是下一个动画在这里停止。如果你改变你的代码东西..这可能不是最佳解决方案..但只需确保在停止电影之前播放最后一帧。
这会随机导致所有GIF播放速度超过正常值。
这是不可重复的!我可以运行你的代码而不会看到这个问题...这可能意味着它可能与你的标签的UI设计有关..或者GIF中的任何东西......如果你有任何设置,尝试将你的UI设置设置为默认值我们在代码中看不到的其他设置。底线:它在这里正常工作。
2条评论:
最好使用Qt新的信号/插槽语法:
connect(ui->leftButton, &QPushButton::clicked, this, &AnimationBox::prevGIFSlot);
一个好的方法是在你启动对象的逻辑之前放置你的信号/插槽connect()
(在你启动电影的情况下),在你开始的情况下电影..然后..你建立信号/插槽连接..我相信这不是一个好习惯。