QGraphicsScene中显示GIF动图,GIF图片在场景中移动

文章目录

      • 效果图
      • 引言
      • 显示GIF图片(方法一)
      • 显示GIF图片(方法二)
      • GIF图片在场景中运动

效果图

在这里插入图片描述
在这里插入图片描述

引言

  • 当我们想在QGraphicsScene显示或者说绘制一张GIF动图时,该如何处理?
  • Qt中的 QGraphicsItempaint 函数中,你不能直接绘制 GIF 动图。paint 函数是用来绘制 QGraphicsItem 的当前状态的,它不支持动画。QGraphicsItem 是一个静态的对象,它不具备播放动画的能力。

显示GIF图片(方法一)

  • 可以结合QMovieQGraphicsItem来展示GIF动画
  1. 创建一个自定义的QGraphicsItem
  2. 使用QMovie来加载GIF文件,并通过信号和槽机制接受帧更新。
  3. 当GIF的新帧可用时,更新绘制的QGraphicsItem
  4. QGraphicsItem的paint()函数将绘制来自QMovie的当前帧。
class AnimatedGifItem : public QGraphicsItem
{
public:AnimatedGifItem(const QString &fileName, QGraphicsItem *parent = nullptr): QGraphicsItem(parent), movie(new QMovie(fileName)){QObject::connect(movie, &QMovie::frameChanged, [this](int /*frame*/){// 在每个新帧上触发重绘this->update(); });movie->start();}~AnimatedGifItem(){delete movie;}QRectF boundingRect() const override{return movie->currentPixmap().rect();}void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override{Q_UNUSED(option);Q_UNUSED(widget);auto pixmap = movie->currentPixmap();QPixmap scaledPixmap = pixmap.scaled(100, 100, Qt::KeepAspectRatio, Qt::SmoothTransformation);painter->drawPixmap(0, 0, scaledPixmap);}private:QMovie *movie;
};
  • 然后只需要new出这些item并设置好位置加入到场景中即可

显示GIF图片(方法二)

  • 你可以通过将 QMovie对象作为 QGraphicsProxyWidget 添加到 QGraphicsScene 中来显示 GIF 动图,以QLabel为载体。
    QMovie *movie = new QMovie("C:\\Users\\KL162\\Desktop\\kk.gif", QByteArray(), nullptr);// 获取GIF动画的原始大小QSize movieSize = movie->scaledSize();// 设定新的大小,保持宽高比int scaledWidth = 200; // 或者其他你想要的宽度QSize scaledSize = movieSize.scaled(scaledWidth, scaledWidth, Qt::KeepAspectRatio);QGraphicsProxyWidget *proxyWidget = new QGraphicsProxyWidget();QLabel *label = new QLabel;label->setMovie(movie);label->setFixedSize(scaledSize);movie->start();proxyWidget->setWidget(label);proxyWidget->setPos(0, 0);scene.addItem(proxyWidget);

GIF图片在场景中运动

  • 要使图片在QGraphicsScene中随机移动,你可以使用 QTimer 来定期更改它的位置。以下是如何实现这个功能的步骤:
  1. 创建一个 QTimer 对象。
  2. 连接 QTimer 的 timeout 信号到一个槽函数,该槽函数将移动 QGraphicsProxyWidget。
  3. 启动 QTimer。
    QGraphicsScene scene;scene.setSceneRect(0, 0, 600, 600);scene.setItemIndexMethod(QGraphicsScene::NoIndex); // 设置场景的项索引方法,NoIndex表示场景不使用索引来优化项的遍历和碰撞检测。// AnimatedGifItem *gifItem = new AnimatedGifItem("C:\\Users\\KL162\\Desktop\\kk.gif");// AnimatedGifItem *gifItem2 = new AnimatedGifItem("C:\\Users\\KL162\\Desktop\\kk.gif");// AnimatedGifItem *gifItem3 = new AnimatedGifItem("C:\\Users\\KL162\\Desktop\\kk.gif");// gifItem->setPos(100, 100);// gifItem2->setPos(400, 400);// gifItem3->setPos(300, 300);// scene.addItem(gifItem);// scene.addItem(gifItem2);// scene.addItem(gifItem3);QMovie *movie = new QMovie("C:\\Users\\KL162\\Desktop\\kk.gif", QByteArray(), nullptr);// 获取GIF动画的原始大小QSize movieSize = movie->scaledSize();// 设定新的大小,保持宽高比int scaledWidth = 200; // 或者其他你想要的宽度QSize scaledSize = movieSize.scaled(scaledWidth, scaledWidth, Qt::KeepAspectRatio);QGraphicsProxyWidget *proxyWidget = new QGraphicsProxyWidget();QLabel *label = new QLabel;label->setMovie(movie);label->setFixedSize(scaledSize);movie->start();proxyWidget->setWidget(label);proxyWidget->setPos(0, 0);scene.addItem(proxyWidget);QGraphicsView *view = new QGraphicsView(&scene);view->setRenderHint(QPainter::Antialiasing);                            // 设置视图的渲染提示,开启抗锯齿,以提高绘制质量view->setCacheMode(QGraphicsView::CacheBackground);                     // 设置视图的缓存模式,缓存背景以提高性能。view->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate); // 设置视图的视口更新模式,只有当项的边界矩形发生变化时才更新视口view->setDragMode(QGraphicsView::ScrollHandDrag);                       // 设置视图的拖动模式,允许用户通过拖动来移动视图view->resize(400, 300);view->show();// 创建一个 QTimer 对象QTimer *timer = new QTimer();// 连接 QTimer 的 timeout 信号到一个槽函数QObject::connect(timer, &QTimer::timeout, [&](){// 获取随机生成器实例QRandomGenerator *randGen = QRandomGenerator::global();// 随机生成新的 x 和 y 坐标int newX = randGen->bounded(scene.width() - proxyWidget->boundingRect().width());int newY = randGen->bounded(scene.height() - proxyWidget->boundingRect().height());// 设置 QGraphicsProxyWidget 的新位置proxyWidget->setPos(newX, newY); });// 启动 QTimertimer->start(1000); // 每秒移动一次
  • 此处以方法二的为例的,使用方法一显示图片在场景中一样可移动

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/452244.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【开源】WordPress一键崩溃宕机插件(整活娱乐)

插件介绍 可一键实现Wordpress崩溃宕机的整活向插件(请勿用于非法途径,仅供整活娱乐)。鼓励关注网站性能的提升,以提供更好的用户体验,提倡为用户提供良好体验和高效速度的原则。 介绍 长期以来,人们都在…

暗黑童话《潘神的迷宫》赏析

故事背景 《潘神的迷宫》是一部由吉尔莫德尔托罗执导的墨西哥电影,讲述了一个结合了幻想、战争、童话和现实主义元素的故事。影片发生在西班牙内战期间,主要通过一名名叫奥菲莉亚的女孩的视角来展开。 故事梗概: 奥菲莉亚和她怀孕的母亲卡…

如何排查常规软件问题 - 面向 Linux 初级用户的教程

笔者从 14 年做开源软件以来,接触了众多 Linux 新手用户,这里我为这类用户总结了一些常见的问题排查方法,希望能帮助到大家。如果你已经工作多年,对于下面提到的思路和方法应该非常熟悉,如果对某一条感到陌生&#xff…

Stable Diffusion 模型下载:ReV Animated

模型介绍 该模型能够创建 2.5D 类图像生成。此模型是检查点合并,这意味着它是其他模型的产物,以创建从原始模型派生的产品。 条目内容类型大模型基础模型SD 1.5来源CIVITAI作者s6yx文件名称revAnimated_v122EOL.safetensors文件大小5.13GB 生成案例 …

瑞_23种设计模式_工厂模式

文章目录 1 什么是工厂模式案例案例代码 2 简单工厂模式(Simple Factory)2.1 简单工厂模式的结构2.2 案例改进——简单工厂模式2.3 案例改进代码实现2.4 简单工厂模式优缺点2.5 拓展——静态工厂 3 工厂方法模式(Factory Method)★…

【爬虫实战】全过程详细讲解如何使用python获取抖音评论,包括二级评论

简介: 前两天,TaoTao发布了一篇关于“获取抖音评论”的文章。但是之前的那一篇包涵的代码呢仅仅只能获取一级评论。虽然说抖音的一级评论挺精彩的了,但是其实二级评论更加有意思,同时二级评论的数量是很多。所以二级评论是非常值…

React Native学习记录

一、创建RN项目的时候是空文件夹的问题 1.使用npx react-native init RNDemos初始化项目的时候,会报错,模版错误,然后创建出来一个空的文件夹 2.如果出现这种情况,需要设置npm install -g react-native-cli 3.安装完成以后再次初…

关于Django部署

首先了解一下开发环境服务器跟生产环境服务器有何不同。 一、我们通过 python manage.py runserver 启动开发环境服务器,这条命令背后做了哪些事情? 1、首先加载Django项目的设置(settings) 2、检查数据库迁移,确保数…

信任与创新 | 回顾通付盾的2023!

-END- 数信云,基于区块链与人工智能的数据安全应用与服务平台

nodejs学习计划--(八)MongoDB数据库

MongoDB 1. 简介 1. Mongodb 是什么 MongoDB 是一个基于分布式文件存储的数据库,官方地址 https://www.mongodb.com/ 2. 数据库是什么 数据库(DataBase)是按照数据结构来组织、存储和管理数据的 应用程序 3. 数据库的作用 数据库的主要…

苹果电脑Mac清理内存怎么清理卸载残留

苹果电脑中的应用程序大部分是可以通过将其拖拽至废纸篓并倾倒来卸载的。但是部分程序在卸载后仍有残留文件,比如support文件和pref设置等文件的。小编今天介绍下苹果电脑清理内存怎么清理卸载残留以及好用的清理技巧分享。 一、苹果电脑清理内存怎么清理卸载残留 …

2024年美赛数学建模F题思路分析 - 减少非法野生动物贸易

# 1 赛题 问题F:减少非法野生动物贸易 非法的野生动物贸易会对我们的环境产生负面影响,并威胁到全球的生物多样性。据估计,它每年涉及高达265亿美元,被认为是全球第四大非法交易。[1]你将开发一个由数据驱动的5年项目&#xff0c…