用Qt将一组静态连续图片制作成动图(定时器和QPixmap实现)

效果图

在这里插入图片描述
由于视频大小限制和录制软件的原因,此图效果可能不是很好,在工程运行生成的Dialog窗口中,效果是非常不错的

项目文件

建立项目后,找到项目路径,建立新的文件夹,命名时不要出现中文,将静态连续图片导入到该新建的文件夹中,回到Qt Creator中,在项目中新建资源文件,并导入图片

完成后的项目文件如图所示

在这里插入图片描述

备注:

如果资源文件过多,可在pro文件中添加代码:

CONFIG += resources_big

以防止 error:out of memory allocating

代码:

dialog.h:

//dialog.h
#ifndef DIALOG_H
#define DIALOG_H


#include <QDialog>


QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE


class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();

    void paintEvent(QPaintEvent * event);

    void timerEvent(QTimerEvent * event);

    int counter;

    void MyPixmap();

private:
    QPixmap PixmapBox[100];

    Ui::Dialog *ui;
};
#endif // DIALOG_H

在此头文件中

public:声明了两个事件 —— 绘图事件和定时器事件,一个int型变量counter(计数器),一个函数MyPixmap()

private:私有成员PixmapBox[100],这就像是一个有100个元素的数组,每个元素都是一个QPixmap类

dialog.cpp:

//dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include <QPainter>
#include <QPixmap>


Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);
   
    this->resize( QSize( 768, 432 ));
   
    MyPixmap();

    counter = 0;

    startTimer(50);

}


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


void Dialog::paintEvent(QPaintEvent * event)
{
    Q_UNUSED(event);//event参数未使用
    QPainter painter(this);
    QRect q1(0,0,1920,1080);
    QRect q2(0,0,width(),height());
    painter.drawPixmap(q2,PixmapBox[counter],q1);
}


void Dialog::timerEvent(QTimerEvent *event)
{
   Q_UNUSED(event);//event参数未使用
   counter++;


   if(counter >= 100)
       counter = 0;


   repaint();
}


void Dialog::MyPixmap()
{
    for(int i = 0;i < 100;i++)
    {
        QString fileName = QString("://Katou Megumi_000/Katou Megumi_0%0.jpg").arg(i,2,10,QLatin1Char('0'));
        QPixmap map(fileName);


        PixmapBox[i] = map;
    }
 }

构造函数中,语句

this->resize( QSize( 768, 432 ));

将窗口大小改变,建议按照图片分辨率进行等比拉伸

然后,调用了MyPixmap()函数,转到它的定义,定义中的这段代码

 for(int i = 0;i < 100;i++)
    {
        QString fileName = QString("://Katou Megumi_000/Katou Megumi_0%0.jpg").arg(i,2,10,QLatin1Char('0'));
        QPixmap map(fileName);

        PixmapBox[i] = map;
    }

QString fileName,声明一个名为fileName的类,内容是string类型": //Katou Megumi_000/Katou Megumi_0%0.jpg",arg函数用于替代字符串中的百分值,也就是
i=0时,fileName=": //Katou Megumi_000/Katou Megumi_000.jpg",
i=1时,fileName=": //Katou Megumi_000/Katou Megumi_001.jpg"

i=99时,fileName=": //Katou Megumi_000/Katou Megumi_099.jpg"
参数中的2是指定填充到并填充字符fillChar= QLatin1Char('0 '))(数字0,ASCII 48)的最小空间量
参数中的10是基参数指定将整数a转换为字符串时要使用的基,表示10进制

(我的理解可能不正确,欢迎指正,详见Qt帮助文档)

如果是从001.jpg开始,将arg参数列表中的i替换为i+1即可,当资源文件超过一百时,以200为例

for(int i = 0;i < 100;i++)
    {
        QString fileName = QString("://Katou Megumi_000/Katou Megumi_0%0.jpg").arg(i,2,10,QLatin1Char('0'));
        QPixmap map(fileName);


        PixmapBox[i] = map;
    }
    for(int i = 100;i < 200;i++)
    {
        QString fileName = QString("://Katou Megumi_000/Katou Megumi_%0.jpg").arg(i,2,10,QLatin1Char('0'));
        QPixmap map(fileName);
//注意到字符串中0的数量的改变

        PixmapBox[i] = map;
    }

fileName的内容填充好后,用QPixmap类将图片传入,并将此QPixmap的类传入到PixmapBox[]的数组中,以便调用

然后回到构造函数,将counter(计数器)初始化,启用定时器,定时器每隔50毫秒启动一次,间隔取决于帧率,由于没有结束语句killTimer(),定时器会一直发生,定时器发生时,调用timerEvent(QTimerEvent *event),转到timerEvent(QTimerEvent *event)

 counter++;

   if(counter >= 100)
       counter = 0;

   repaint();
  

计数器自加,用于切换帧,如果counter>=100时,即所有的帧都播放完毕后,counter赋值为0,repaint()调用此counter值下的paintEvent(QPaintEvent *event)事件,转到
paintEvent(QPaintEvent *event)

    QPainter painter(this);
    QRect q1(0,0,1920,1080);
    QRect q2(0,0,width(),height());
    painter.drawPixmap(q2,PixmapBox[counter],q1);
    }

QPaint painter(this)创建绘图对象,q1为源,q2为目标,源矩形从坐标(0,0)起,宽为1920,高为1080,参照资源图片的分辨率,目标矩形从坐标(0,0)起,获取Dialog的宽和高,绘图对象绘制源矩形大小的QPixmap类,此类被储存在PixmapBox[]的数组中,通过计数器的当前值进行调用,然后绘图对象将其拉伸到目标矩形的大小,此后,资源图片正好铺满整个Dialog窗口

备注:

在这里插入图片描述
出现了此情况,是因为函数参数未使用,这是正常的现象,个人认为此警告意义不大

解决办法:在该函数下添加语句

   Q_UNUSED(event);//event参数未使用

参考:

Qt下编译警告warning: unused parameter参数未使用(https://blog.csdn.net/lvdepeng123/article/details/79252968)

解决cc1plus.exe: error: out of memory allocating

等博客

个人初学,理解尚浅,若有错误,欢迎指正

  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值