【问题标题】:Switch between GIF animations with QMovie and signals/slots in Qt在 QMovie 和 Qt 中的信号/插槽之间切换 GIF 动画
【发布时间】:2016-06-08 04:31:25
【问题描述】:

我正在尝试在 Qt 中使用 QMovie 来播放两个 GIF。 当一个 gif 结束时,我需要播放下一个。

问题就在这里。我想将信号连接到插槽,以便知道 GIF 动画何时结束。这是我的代码示例:

#include "abv.h"
#include "ui_abv.h"
#include "qmovie.h"
#include "qlabel.h"
#include <iostream>
#include <QString>
#include <QDebug>
#include <QObject>

using namespace std;

abv::abv(QWidget *parent) :
    QDialog(parent, Qt::FramelessWindowHint),
    ui(new Ui::abv)
{
    QString project = projectGifs();//projectGifs() is a function stated in my header that sends over a randomly selected gif
    QMovie* movie = new QMovie(project);
    if (!movie->isValid())
    {
        cout << "The gif is not valid!!!";
    }
    QLabel* label = new QLabel(this);
    QObject::connect(
                movie, SIGNAL(frameChanged(int)),
                this, SLOT(abv::abv()));//stop animation and get new animation
    label->setMovie(movie);
    movie->start();
}

void abv::detectEndFrame(int frameNumber)
{
    if(frameNumber == (movie->frameCount()-1))
    {
        movie->stop();
    }
}

abv::~abv()
{
    delete ui;
}

if(frameNumber == movie-&gt;frameCount()-1),我收到一条错误消息,指出电影未声明。它还指出left of '-&gt;framecount' must point to class/struct/union/generic type

movie-&gt;stop(); 也是如此:看来我可以访问变量 movie

由于同样的问题,我似乎也无法用新的 GIF 替换我的电影。 我该如何解决?插入新的 GIF 动画应该注意什么?

【问题讨论】:

    标签: c++ qt animation


    【解决方案1】:

    首先,为了消除错误,只需在你的头文件中声明你的QMovie(我相信是名为abv.h的那个)。

    在你的 .h 中:

    private : 
        QMovie* _movie;
    

    在您的 .cpp 中:

    abv::abv(QWidget *parent) :
        QDialog(parent, Qt::FramelessWindowHint),
        ui(new Ui::abv)
    {
        QString project = projectGifs();
        _movie = new QMovie(project); // this line changes
        ...        
    

    现在,您将信号 frameChanged(int) 连接到构造函数 abv::abv()。它不起作用,因为:

    • 主要是,你的构造函数不能是槽;
    • 签名不一样(槽必须采用int作为参数,就像信号一样)

    而且,你为什么要这样?每次将新图像发送给用户(!)时,都会发出信号 frameChanged(int)。您当前正在告诉您的程序在每次帧更改时启动一个新的 GIF。你的代码不会这样工作。

    如果我理解得很好,您只需将信号 QMovie::finished() 连接到您将调用另一个 GIF 的插槽。您的 QLabel 也必须是一个类变量。像这样的:

    在你的 .h 中:

    private
        QMovie* _movie;
        QLabel* _label;
    
    public slots :
        void startNewAnimation();
    

    在你的 .cpp 中:

    abv::abv(QWidget *parent) :
        QDialog(parent, Qt::FramelessWindowHint),
        ui(new Ui::abv)
    {
        QString project = projectGifs(); //projectGifs() is a function stated in my header that sends over a randomly selected gif
        _movie = new QMovie(project);
        if (!_movie->isValid())
            cout << "The gif is not valid!!!";
        _label = new QLabel(this);
        QObject::connect(
                    _movie, SIGNAL(finished()),
                    this, SLOT(startNewAnimation())); //stop animation and get new animation
        _label->setMovie(_movie);
        _movie->start();
    }
    
    void abv::startNewAnimation()
    {
        // here you need to call your new GIF
        // and then you just put it in your label
    
        // you can also disconnect the signal finished() if you want
    
        QString newGIF = projectGifs();
        _movie = new QMovie(newGIF);
        _label->setMovie(_movie);
    }
    

    【讨论】:

    • 我会在几个小时后试一试(当我回到家时)。在回去阅读 QMovie 文档和示例之后,我意识到你和那些文档对于私有变量是完全正确的——我完全错过了它们。为了响应 frameChanged(int) 与 finished(),我尝试了两者,以防我的视频循环播放(例如 gif 图像)。如果它检测到真正的最后一帧,我想进行备份。不过我会把它改成finished()!非常感谢!
    • 是的,试试看,如果您有更多问题,请不要犹豫回到这里 :)
    • 好的,我现在在家。我试了一下,它抛出了一大堆错误(意外的标记'class'。你忘记了';')和一大堆其他说明符 -int 也假设了错误。这些东西大部分位于 moc_abv.cpp 文件和 qinputmethod.h 文件中。不太清楚该怎么做。
    • 编辑:我已经修复它,它似乎正在工作!我会回来PM你或在这里发帖问另一个问题。但就我而言,这已经解决了我的问题! :) 谢谢 IAmlnPLS!
    • 很高兴听到它 :) 希望你能成功,听起来很有趣!
    猜你喜欢
    • 1970-01-01
    • 2010-12-03
    • 1970-01-01
    • 1970-01-01
    • 2017-08-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-15
    相关资源
    最近更新 更多