iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Qt实现炫酷启动图动态进度条效果
  • 875
分享到

Qt实现炫酷启动图动态进度条效果

2024-04-02 19:04:59 875人浏览 泡泡鱼

Python 官方文档:入门教程 => 点击学习

摘要

目录一、简述二、动效进度条1、光效进度条2、延迟到达进度条3、接口说明三、启动图1、实现思路2、背景图切换四、测试1、构造启动图2、背景图3、其他信息4、事件循环五、源码一、简述 最

一、简述

最近接到一个新需求,让做一个动效进度条。

由于我们的产品比较大,在软件启动的时候会消耗比较长的时间,原生的进度条已经不能满足我们的需求,这里我们就需要一个会动的进度条,效果如下图所示。

光效进度条主要是做了一个进度动画,在已完成的部分上进行快速的迭代渲染,给用户一种直观感受,我们的软件一直努力加载,它还活着。

有了这个进度条之后,当我们的进度从40%到50%这个持续的过程中,界面再也不会出现假死的情况,是不是很完美呢。。。

下面我就来分析下这个动效进度条是怎么做的

二、动效进度条

如效果图所示,光效进度条不同于一般的进度条,他在基础的任务进度之上还添加了一层光效,主要是想告诉用户我们的软件一直在努力运行,请在耐心的等待一下下。

我自己在做功能的时候,往往喜欢先做一个测试demo,然后在把做好的功能集成在正式环境,这个功能也不列外,如第一节中展示的效果图,就是测试demo的样子,虽然很丑,但是基础功能是有的。

现在的很多软件,在进度展示上都有了比较绚丽的效果,比如压缩软件,解压文件的时候都会有动效进度条,用过的同学应该都知道长啥样,而我们的光效进度条跟这个效果差不多,除此之外我们还提供了另一种动效,延迟动效,他们两个在一定程度上都展示了更友好的进度效果。

在开始分析功能前,首先我们先来考虑下我们的需求:动效进度条,也就是说在原来的进度条基础上需要添加实时动画,让进度条看起来更炫酷一些,除了光效进度条以外,还有一种延迟到达进度条,也属于动态进度条。

延迟动效、说直白一点儿就是延迟到达,当我们设置了进度从10%到20%时,程序模拟了一个渐进的过程,使用一个时间段走完了这10%的进度。

下面我们分别来介绍这两种进度条的实现

实现炫酷的进度条我们可以从QWidget自定义开始写,也就是说从头开始写,但通常我们不这样干,因为这样可能会写出无穷无尽的bug,而且现有的轮子已经很稳定了,为什么还要造呢。

1、光效进度条

光效进度条我们使用了一个小技巧,采用一个简单的办法实现,我们的光效进度条控件继承自Qt原生进度条类QProgressBar,在新类中我们只需要在Qt绘制完原生进度条之后,补画动效即可。

a、paintEvent函数

paintEvent函数是Qt的绘制函数,当界面刷新的时候,这个接口函数就会被调用,因此我们需要重写这个接口,首先调用父窗口的绘制方法,然后我们在绘制我们自己的动效,代码如下所示

QProgressBar::paintEvent(event);
drawCache绘制动效

b、drawCache绘制动效

绘制动效的时候,我们需要知道动效的绘制区域,这个地方我们需要主动去解析qss的一些参数,Qt的style()->subElementRect这个接口刚好可以拿到我们需要的信息

下面简单描述下我们的实现流程

  • 首先我们获取进度条的几何大小和中间进度的几何大小,这样的话我们就可以计算出来各border的数值
  • 然后根据我们当前的value值就可以计算出进度条已经走过(就是值小于我们设定的区域)的几何大小
  • 我们的光效将是跑在第二步计算出来的区域上,一直循环迭代
  • 内存里我们维护一个cacheValue,这个值在每次界面刷新的时候递增,但是不能大于第二步的value值,cacheValue将是我们动效绘制的一个关键参数,他表示了动效绘制的长度
  • 构造一个渐变刷子,设置给QPainter
  • 绘制动效

上下大致描述了下绘制动效的一个流程,下面送上具体代码,由于篇幅原因,代码我进行了部分伪代码处理。


void GMPProgressBar::drawCache()
{
    QStyleOptionProgressBarV2 opt;
    QRect outerRect = style()->subElementRect(QStyle::SE_ProgressBarGroove, &opt, this);
    QRect innerRect = style()->subElementRect(QStyle::SE_ProgressBarContents, &opt, this);
    QMargins borders(构造一个QMargins);

	QRectF rect(动效绘制区域);

	if (m_iCacheValue != 0)
	{
		QPainter painter(this);
		QLinearGradient gradient(构造绘图刷子);
		painter.setBrush(gradient);
		painter.drawRoundedRect(rect, 2, 2);
	}
}

c、定时刷新

由于我们的动效是需要主动去刷新的,因此我们需要声明一个定时器,然后定时去刷新,实现代码可能像下面这样


connect(m_pCacheTimer, &QTimer::timeout, this, [this]{
		if (TM_CACHE == m_mode)
		{
			++m_iCacheValue;
			repaint();
		}else
        {
            m_pCacheTimer->stop();
        }
	});

定时器只需要在我们第一次设置进度条值的时候启动,或者当我们设置一个新的值,而定时器没有启动,我们就需要去激活定时器。

TM_CACHE模式即是我们的动效模式,TM_SMOOTH模式则是我们的延迟到达模式


connect(this, &QProgressBar::valueChanged, [this](int value){//TM_CACHE模式下 启动动画时机
		if (!m_pCacheTimer->isActive() && value != 0 && TM_CACHE == m_mode)
		{
			m_pCacheTimer->start(m_iRefreshleveling);
		}
	});

动效进度条效果如下图所示

2、延迟到达进度条

动效进度条可能更适用于启动界面,但是也有一些时候,我们可能需要更平缓的一个加载曲线,例如安装软件、卸载软件的时候。

a、setValue

延迟到达进度条和动效进度条的实现方式就有所差别了,对于实现延迟到达进度条,我们这里重写了setValue函数,当外部调用该接口设置value值时,我们并没有立即去设置当前值,而是使用了一个时间段去完成这个值得刷新。

  • 外部调用setValue时,我们首先计算出我们应该绘制的最大宽度PixelMax、当前已经绘制到的最大宽度cacheValue和我们的步长
  • 设置定时器刷新频率,并重启定时器
  • 定时器刷新时,cacheValue自增我们的步长
  • 调用父类的QProgressBar::setValue接口设置值

b、定时器

延迟达到功能的的定时器和之前我们什么的动效定时器可以混用一个,我们定时器刷新的时候,针对不同的动画模式,我们执行不同的的代码即可,实现代码可能像下面这样


connect(m_pCacheTimer, &QTimer::timeout, this, [this]{
	if (TM_CACHE == m_mode)
	{
		++m_iCacheValue;
		repaint();
	}
	else if (TM_SMOOTH == m_mode)
	{
		changeSmooth();
	}
    else
    {
        m_pCacheTimer->stop();
    }
});

延迟到达进度条效果如下图所示

3、接口说明

光效进度条类对外只暴露了3个接口,分别是设置动画模式、动画时长和刷新频率

特别需要注意的是,我们这里重写了父类的setValue接口,这意味着我们不能使用多态来操作这个接口


void setTransitionMode(TransitionMode mode);//设置动画模式
void setSmoothDuration(int duration);//设置刷新总时长 模式为TM_SMOOTH时有效
void setRefreshleveling(int rate);//设置刷新频率 每次更改TransitionMode之后会变为默认值

a、修改动画模式

修改动画模式的时候,我们需要清空内存中的所有数据,并把value值设为0。


void GMPProgressBar::setTransitionMode(TransitionMode mode)
{
	if (m_mode == mode)
	{
		return;
	}

	m_mode = mode;
	clearData();

	QProgressBar::setValue(0);
}

b、其他接口

设置刷新时长和频率接口都比较简单,不做特别说明

特别注意:这个3个接口最好是在动画启动前设置,动画开始后尽量不要去调用

三、启动图

第二节我们主要是讲述了怎么做一个动效进度条,这一节我们来做一个启动图页面,把这个动效使用进去。

启动图不是我们主要分析的内容,这个我就简单说下这个类的实现方式和一些借口说明

1、实现思路

Qt已经给我们提供了一个QSplashScreen,但是使用起来还是特别有限,因此这里我把Qt的源码直接进行了二次开发

  • 首先Qt的原生实现方式基本都被移植了出来
  • 启动图使用了简单的上下布局,上面是一张我自绘制的图片,放在了一个QLabel上,下面是动效进度条
  • 自绘制的图片上包括了,产品名称、loGo、背景图等等

2、背景图切换

当我们调用setPixmap设置背景图时,如果我们指定了多张图,我将会启动一个定时器,在指定时长后重新构造一张大的背景图,并添加到启动窗口上

这里主要说明下背景图是怎么构造出来的,代码如下所示

a、根据背景图构造启动图大小,并移动到屏幕中间


m_currentPixmap = m_lstPixmaps.at(m_iCurrentIndex);

QRect size(QPoint(), m_currentPixmap.size()  / m_currentPixmap.devicePixelRatio());
size.setHeight(size.height() + StatusBarHeight);
setFixedSize(size.size());
m_pProgressBar->setFixedWidth(size.width() / 8 * 3);
move(QApplication::desktop()->screenGeometry().center() - size.center());

b、绘制程序logo


QPainter painter(&m_currentPixmap);
painter.drawPixmap(m_startPos, m_logo);

c、绘制标题栏


painter.save();
painter.setFont(m_titleFont);

QFontMetrics fontMetrics(m_titleFont);
int textWidth = fontMetrics.width(m_strWindowTitle);
int textHegith = m_logo.height();
QRect textTect = QRect(m_startPos + QPoint(13 + m_logo.width(), 0), QSize(textWidth, textHegith));
painter.drawText(textTect, m_strWindowTitle, QTextOption(Qt::AlignCenter));
painter.restore();

d、设置给QLabel背景图

m_pWindowBackground->setPixmap(m_currentPixmap);

启动图的效果这里就不在贴图了,第三节上的两个gif图都是最终的启动图效果

四、测试

最后就是测试代码了,主要是模拟了程序的一个加载过程

1、构造启动图

首先我们构造一个启动图对象,并设置程序logo和动画模式


GMPSplashScreen * screen = new GMPSplashScreen(QPixmap(":/splashScreen/start.png"));
screen->show();
screen->setLogo(QIcon("logo.ico").pixmap(48, 48));
screen->setTransitionMode(GMPProgressBar::TM_CACHE);

2、背景图

设置背景图,并设置背景图更换时间间隔


QList<QPixmap> lstPixmap;
lstPixmap.append(QPixmap(":/splashScreen/start.png"));
lstPixmap.append(QPixmap(":/splashScreen/start.jpg"));
screen->setPixmap(lstPixmap, 2000);

3、其他信息

设置程序的提示信息和标题栏


screen->showMessage("Established connections", 0);
screen->setTitle(QStringLiteral("广联达BIM土建计量GTJ2018"));

4、事件循环

这里写了一个死循环,主要是为了模拟程序的一个加载过程,每隔10ms处理下界面刷新事件


a.processEvents();

while (1)
{
    QTest::qSleep(10);
    a.processEvents();
}
splashScreen w;
w.show();

screen->finish(&w);

五、源码

需要源码的留邮箱,现在的csdn简直太坑爹了。。。

到此这篇关于Qt实现炫酷启动图动态进度条效果的文章就介绍到这了,更多相关Qt动态进度条内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: Qt实现炫酷启动图动态进度条效果

本文链接: https://www.lsjlt.com/news/157435.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Qt实现炫酷启动图动态进度条效果
    目录一、简述二、动效进度条1、光效进度条2、延迟到达进度条3、接口说明三、启动图1、实现思路2、背景图切换四、测试1、构造启动图2、背景图3、其他信息4、事件循环五、源码一、简述 最...
    99+
    2024-04-02
  • vue实现动态进度条效果
    本文实例为大家分享了vue实现动态进度条效果的具体代码,供大家参考,具体内容如下 演示效果: 结构 progress/index.js const controller = ...
    99+
    2024-04-02
  • Android中怎么实现一个炫酷进度条效果
    这期内容当中小编将会给大家带来有关Android中怎么实现一个炫酷进度条效果,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。HorizontalProgressbarWithProgress的代码impor...
    99+
    2023-05-30
    android
  • Python如何实现炫酷的动态图
    这篇文章主要为大家展示了“Python如何实现炫酷的动态图”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Python如何实现炫酷的动态图”这篇文章吧。启动如果你还没安装 Plotly,只需在你的...
    99+
    2023-06-28
  • Python如何实现酷炫进度条
    这篇文章主要介绍了Python如何实现酷炫进度条的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Python如何实现酷炫进度条文章都会有所收获,下面我们一起来看看吧。1、自定义ProgressBar最原始的办法就...
    99+
    2023-06-30
  • bootstrap进度条动态加载效果怎么实现
    要实现进度条的动态加载效果,可以使用Bootstrap的进度条组件,并结合JavaScript来更新进度条的值。首先,在HTML中添...
    99+
    2023-08-24
    bootstrap
  • HTML5中Canvas如何实现酷炫大波浪进度图效果
    这篇文章主要介绍了HTML5中Canvas如何实现酷炫大波浪进度图效果,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解...
    99+
    2024-04-02
  • vue中使用animate.css实现炫酷动画效果
    目录1.安装(在vscode终端中,使用npm安装)2.引入3.代码实现animate.css 是一个来自国外的 CSS3 动画库,它提供了抖动(shake)、闪烁(flash)、弹...
    99+
    2024-04-02
  • 如何在HTML5中实现一个超炫酷粒子效果的进度条
    如何在HTML5中实现一个超炫酷粒子效果的进度条?针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。JavaScript代码  var lightL...
    99+
    2023-06-09
  • css+js怎么实现简单的动态进度条效果
    这篇文章主要介绍css+js怎么实现简单的动态进度条效果,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!   我们要知道,这里主要使用了css3的animation动画属性,首先将进...
    99+
    2024-04-02
  • 实现炫酷滚动效果的CSS属性技巧
    实现炫酷滚动效果的CSS属性技巧,需要具体代码示例CSS是网页设计中不可或缺的一部分,通过CSS可以实现各种各样的效果来提升网页的交互体验。其中,滚动效果是一种非常常见也非常炫酷的效果,它可以使网页元素以流畅的动画效果滚动到指定位置。本文将...
    99+
    2023-11-18
    技巧 滚动效果 CSS属性
  • 基于Three.js实现酷炫3D地图效果
    目录实现效果前言使用1.修改整体的背景图可以使用颜色或用贴图改材质2. 取消地图上柱状图显示3.更换地图、更换省份、市 4.修改相机的视角,页面展示的远近角度5....
    99+
    2022-11-13
    Three.js 3D地图 Three.js 地图
  • 如何使用CSS实现酷炫充电动画效果
    这篇文章给大家分享的是有关如何使用CSS实现酷炫充电动画效果的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。css是什么意思css是一种用来表现HTML或XML等文件样式的计算机语言,主要是用来设计网页的样式,使网...
    99+
    2023-06-14
  • AndroidFlutter实现五种酷炫文字动画效果详解
    目录前言波浪涌动效果波浪线跳动文字组彩虹动效滚动广告牌效果打字效果其他效果自定义效果总结前言 偶然逛国外博客,看到了一个介绍文字动画的库,进入 pub 一看,立马就爱上这个动画库了,...
    99+
    2024-04-02
  • 3种Python实现酷炫进度条的实用方法
    目录1、自定义ProgressBar2、tqdm3、Rich前言: 在下载某些文件的时候你一定会不时盯着进度条,在写代码的时候使用进度条可以便捷的观察任务处理情况。 除了使用 pri...
    99+
    2024-04-02
  • Qt编写地图实现实时动态轨迹效果
    目录一、前言二、功能特点三、体验地址四、效果图五、相关代码一、前言 实时动态轨迹经历过很多个版本的迭代,此功能最初是一个客户定制的,主要是需要在地图上动态显示GPS的运动轨迹,有个应...
    99+
    2024-04-02
  • Python 数据可视化实现5种炫酷的动态图
    本文将介绍 5 种基于 Plotly 的可视化方法,你会发现,原来可视化不仅可用直方图和箱形图,还能做得如此动态好看甚至可交互。 那么,Plotly 有哪些好处?Plotly 的整合...
    99+
    2024-04-02
  • android实现动态显隐进度条
    本文实例为大家分享了android实现动态显隐进度条的具体代码,供大家参考,具体内容如下 调用 ProgressUtil.startProgress(this, new Prog...
    99+
    2024-04-02
  • Android中怎么自定义ProgressBar实现酷炫进度条
    要在Android中自定义ProgressBar并实现酷炫的进度条效果,你可以按照以下步骤进行操作:1. 创建一个新的自定义Prog...
    99+
    2023-10-18
    Android
  • html如何实现酷炫动态登录页面
    本篇内容介绍了“html如何实现酷炫动态登录页面”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! 代码如下...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作