【Qt控件之QMovie】详解
  yQAl4kecrO8W 2023年12月22日 47 0



Qt控件之QMovies

  • 概述
  • 公共类型
  • 属性
  • 公共函数
  • 公共槽函数
  • 信号
  • 静态公共成员
  • 示例
  • 使用场景


概述

QMovie类是一个方便的类,用于播放具有QImageReader的动画。此类用于显示没有声音的简单动画。如果您想显示视频和媒体内容,请改用Qt多媒体框架Qt Multimedia multimedia framework
首先,通过将文件的名称或包含动画图像格式的QIODevice的指针传递给QMovie的构造函数,创建一个QMovie对象。您可以在开始播放动画之前调用isValid()函数来检查图像数据是否有效。要开始播放动画,请调用start()函数。QMovie将进入Running状态,并发出started()stateChanged()信号。要获取动画的当前状态,请调用state()函数。
要在应用程序中显示动画,您可以将QMovie对象传递给QLabel::setMovie()函数。示例如下:

QLabel label;
 QMovie *movie = new QMovie("animations/fire.gif");

 label.setMovie(movie);
 movie->start();

每当动画中有新帧可用时,QMovie将发出updated()信号。如果帧的大小发生更改,则发出resized()信号。您可以调用currentImage()currentPixmap()函数来获取当前帧的副本。当动画完成时,QMovie发出finished()信号。如果在播放过程中发生任何错误(即,图像文件损坏),QMovie将发出error()信号。
调用setSpeed()函数可以控制动画的播放速度,该函数将原始速度的百分比作为参数。通过调用setPaused(true)函数可以暂停动画。然后,QMovie将进入Paused状态,并发出stateChanged()信号。如果调用setPaused(false)函数,则QMovie将重新进入Running状态并重新开始动画。要停止动画,请调用stop()函数。
某些动画格式允许您设置背景颜色。您可以调用setBackgroundColor()函数来设置颜色,或者调用backgroundColor()函数来获取当前的背景颜色。
currentFrameNumber()函数返回当前帧的序列号。动画中的第一帧序列号为0。如果图像格式支持,frameCount()函数返回动画中的总帧数。可以调用loopCount()函数获取动画在完成之前应循环播放的次数。nextFrameDelay()函数返回当前帧应该显示的毫秒数。
可以通过调用setCacheMode()函数,指示QMovie缓存动画的帧。
调用supportedFormats()函数可以获取QMovie支持的格式列表。

公共类型

  • enum CacheMode { CacheNone, CacheAll } // 缓存模式
  • enum MovieState { NotRunning, Paused, Running } // 动画状态

属性

  • cacheMode : CacheMode // 缓存模式
  • speed : int // 速度

公共函数

  • QMovie(QObject *parent = Q_NULLPTR) // 构造函数
  • QMovie(QIODevice *device, const QByteArray &format = QByteArray(), QObject *parent = Q_NULLPTR)
  • QMovie(const QString &fileName, const QByteArray &format = QByteArray(), QObject *parent = Q_NULLPTR)
  • ~QMovie() // 析构函数
  • QColor backgroundColor() const // 获取背景颜色
  • CacheMode cacheMode() const // 获取缓存模式
  • int currentFrameNumber() const // 获取当前帧的序号
  • QImage currentImage() const // 获取当前帧的QImage对象
  • QPixmap currentPixmap() const // 获取当前帧的QPixmap对象
  • QIODevice *device() const // 获取当前设备
  • QString fileName() const // 获取文件名
  • QByteArray format() const // 获取格式
  • int frameCount() const // 获取动画的总帧数
  • QRect frameRect() const // 获取动画帧的矩形区域
  • bool isValid() const // 检查动画数据是否有效
  • bool jumpToFrame(int frameNumber) // 跳转到指定帧
  • int loopCount() const // 获取动画应循环播放的次数
  • int nextFrameDelay() const // 获取下一帧的延迟时间
  • QSize scaledSize() // 获取缩放尺寸
  • void setBackgroundColor(const QColor &color) // 设置背景颜色
  • void setCacheMode(CacheMode mode) // 设置缓存模式
  • void setDevice(QIODevice *device) // 设置设备
  • void setFileName(const QString &fileName) // 设置文件名
  • void setFormat(const QByteArray &format) // 设置格式
  • void setScaledSize(const QSize &size) // 设置缩放尺寸
  • int speed() const // 获取速度
  • MovieState state() const // 获取动画状态

公共槽函数

  • bool jumpToNextFrame() // 跳转到下一帧
  • void setPaused(bool paused) // 设置暂停状态
  • void setSpeed(int percentSpeed) // 设置速度
  • void start() // 开始播放动画
  • void stop() // 停止动画

信号

  • void error(QImageReader::ImageReaderError error) // 错误信号
  • void finished() // 动画完成信号
  • void frameChanged(int frameNumber) // 帧变化信号
  • void resized(const QSize &size) // 重新调整大小信号
  • void started() // 动画开始信号
  • void stateChanged(QMovie::MovieState state) // 状态变化信号
  • void updated(const QRect &rect) // 更新信号

静态公共成员

  • QList supportedFormats() // 支持的格式列表

示例

先上UI:

【Qt控件之QMovie】详解_qt


实现步骤在代码中有注释。

MoviePlayer.h

#ifndef MOVIEPLAYER_H
#define MOVIEPLAYER_H

#include <QWidget>

QT_BEGIN_NAMESPACE
class QCheckBox;
class QGridLayout;
class QHBoxLayout;
class QLabel;
class QMovie;
class QSlider;
class QSpinBox;
class QToolButton;
class QVBoxLayout;
QT_END_NAMESPACE

class MoviePlayer : public QWidget
{
    Q_OBJECT

public:
    MoviePlayer(QWidget *parent = 0);
    // 打开文件
    void openFile(const QString &fileName);

private slots:
	// 打开槽函数
    void open();
    // 跳转到某帧
    void goToFrame(int frame);
    // 适应窗口
    void fitToWindow();
    // 更新按钮状态
    void updateButtons();
    // 更新帧滑动条
    void updateFrameSlider();
	// 当微调框数据改变时,触发此槽
    void slot_valueChanged(int nPercentSpeed);

private:
	// 创建控件
    void createControls();
    // 创建按钮:开始、暂停、停止
    void createButtons();
	// 目录
    QString currentMovieDirectory;
    QLabel *movieLabel;	// 防止QMoive的控件
    QMovie *movie;	// QMoive对象
    QToolButton *openButton;
    QToolButton *playButton;
    QToolButton *pauseButton;
    QToolButton *stopButton;
    QToolButton *quitButton;
    QCheckBox *fitCheckBox;
    QSlider *frameSlider;
    QSpinBox *speedSpinBox;
    QLabel *frameLabel;
    QLabel *speedLabel;

    QGridLayout *controlsLayout;
    QHBoxLayout *buttonsLayout;
    QVBoxLayout *mainLayout;
};

#endif

MoviePlayer.cpp

#include <QtWidgets>

#include "movieplayer.h"

MoviePlayer::MoviePlayer(QWidget *parent)
    : QWidget(parent)
{
    movie = new QMovie(this);
    movie->setCacheMode(QMovie::CacheAll);

    movieLabel = new QLabel(tr("No movie loaded"));
    movieLabel->setAlignment(Qt::AlignCenter);
    movieLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
    movieLabel->setBackgroundRole(QPalette::Dark);
    movieLabel->setAutoFillBackground(true);

    currentMovieDirectory = "movies";

    createControls();
    createButtons();

    connect(movie, SIGNAL(frameChanged(int)), this, SLOT(updateFrameSlider()));
    connect(movie, SIGNAL(stateChanged(QMovie::MovieState)),
            this, SLOT(updateButtons()));
    connect(fitCheckBox, SIGNAL(clicked()), this, SLOT(fitToWindow()));
    connect(frameSlider, SIGNAL(valueChanged(int)), this, SLOT(goToFrame(int)));
    connect(speedSpinBox, SIGNAL(valueChanged(int)),
            this, SLOT(slot_valueChanged(int)));
    //            movie, SLOT(setSpeed(int)));

    mainLayout = new QVBoxLayout;
    mainLayout->addWidget(movieLabel);
    mainLayout->addLayout(controlsLayout);
    mainLayout->addLayout(buttonsLayout);
    setLayout(mainLayout);

    updateFrameSlider();
    updateButtons();

    setWindowTitle(tr("Movie Player"));
    resize(400, 400);
}

void MoviePlayer::open()
{
    QString fileName = QFileDialog::getOpenFileName(this, tr("Open a Movie"),
                                                    currentMovieDirectory);
    if (!fileName.isEmpty())
        openFile(fileName);
}

void MoviePlayer::openFile(const QString &fileName)
{
    currentMovieDirectory = QFileInfo(fileName).path();

    movie->stop();
    movieLabel->setMovie(movie);
    movie->setFileName(fileName);
    movie->start();

    updateFrameSlider();
    updateButtons();
}

void MoviePlayer::goToFrame(int frame)
{
    movie->jumpToFrame(frame);
}

void MoviePlayer::fitToWindow()
{
    movieLabel->setScaledContents(fitCheckBox->isChecked());
}

void MoviePlayer::updateFrameSlider()
{
    bool hasFrames = (movie->currentFrameNumber() >= 0);

    if (hasFrames) {
        if (movie->frameCount() > 0) {
            frameSlider->setMaximum(movie->frameCount() - 1);
        } else {
            if (movie->currentFrameNumber() > frameSlider->maximum())
                frameSlider->setMaximum(movie->currentFrameNumber());
        }
        frameSlider->setValue(movie->currentFrameNumber());
    } else {
        frameSlider->setMaximum(0);
    }
    frameLabel->setEnabled(hasFrames);
    frameSlider->setEnabled(hasFrames);
}

void MoviePlayer::slot_valueChanged(int nPercentSpeed)
{
    qDebug().noquote() << "[" << __FILE__ << __LINE__ << "]" << "nPercentSpeed :" << nPercentSpeed;
    movie->setSpeed(nPercentSpeed);
}

void MoviePlayer::updateButtons()
{
    playButton->setEnabled(movie->isValid() && movie->frameCount() != 1
            && movie->state() == QMovie::NotRunning);
    pauseButton->setEnabled(movie->state() != QMovie::NotRunning);
    pauseButton->setChecked(movie->state() == QMovie::Paused);
    stopButton->setEnabled(movie->state() != QMovie::NotRunning);
}

void MoviePlayer::createControls()
{
    fitCheckBox = new QCheckBox(tr("Fit to Window"));

    frameLabel = new QLabel(tr("Current frame:"));

    frameSlider = new QSlider(Qt::Horizontal);
    frameSlider->setTickPosition(QSlider::TicksBelow);
    frameSlider->setTickInterval(10);

    speedLabel = new QLabel(tr("Speed:"));

    speedSpinBox = new QSpinBox;
    speedSpinBox->setRange(1, 9999);
    speedSpinBox->setValue(100);
    speedSpinBox->setSuffix(tr("%"));

    controlsLayout = new QGridLayout;
    controlsLayout->addWidget(fitCheckBox, 0, 0, 1, 2);
    controlsLayout->addWidget(frameLabel, 1, 0);
    controlsLayout->addWidget(frameSlider, 1, 1, 1, 2);
    controlsLayout->addWidget(speedLabel, 2, 0);
    controlsLayout->addWidget(speedSpinBox, 2, 1);
}

void MoviePlayer::createButtons()
{
    QSize iconSize(36, 36);

    openButton = new QToolButton;
    openButton->setIcon(style()->standardIcon(QStyle::SP_DialogOpenButton));
    openButton->setIconSize(iconSize);
    openButton->setToolTip(tr("Open File"));
    connect(openButton, SIGNAL(clicked()), this, SLOT(open()));

    playButton = new QToolButton;
    playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
    playButton->setIconSize(iconSize);
    playButton->setToolTip(tr("Play"));
    connect(playButton, SIGNAL(clicked()), movie, SLOT(start()));

    pauseButton = new QToolButton;
    pauseButton->setCheckable(true);
    pauseButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
    pauseButton->setIconSize(iconSize);
    pauseButton->setToolTip(tr("Pause"));
    connect(pauseButton, SIGNAL(clicked(bool)), movie, SLOT(setPaused(bool)));

    stopButton = new QToolButton;
    stopButton->setIcon(style()->standardIcon(QStyle::SP_MediaStop));
    stopButton->setIconSize(iconSize);
    stopButton->setToolTip(tr("Stop"));
    connect(stopButton, SIGNAL(clicked()), movie, SLOT(stop()));

    quitButton = new QToolButton;
    quitButton->setIcon(style()->standardIcon(QStyle::SP_DialogCloseButton));
    quitButton->setIconSize(iconSize);
    quitButton->setToolTip(tr("Quit"));
    connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));

    buttonsLayout = new QHBoxLayout;
    buttonsLayout->addStretch();
    buttonsLayout->addWidget(openButton);
    buttonsLayout->addWidget(playButton);
    buttonsLayout->addWidget(pauseButton);
    buttonsLayout->addWidget(stopButton);
    buttonsLayout->addWidget(quitButton);
    buttonsLayout->addStretch();
}

调用

#include <QApplication>

#include "movieplayer.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MoviePlayer player;
    player.show();
    player.show();
    return app.exec();
}

使用场景

  • 在刷新页面时,可以使用QMovie来实现等待界面。
  • QMovie类也适用于在应用程序中显示电影。通过将QMovie对象传递给QLabel::setMovie(),可以将动画显示在QLabel控件中。

总之,QMovie类适用于需要播放简单动画或实现等待界面的各种场景。


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年12月22日 0

暂无评论

推荐阅读
  anLrwkgbyYZS   2023年12月30日   33   0   0 ideciciMaxideMax
yQAl4kecrO8W