范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

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

  一、简述
  在软件启动的时候会消耗比较长的时间,原生的进度条已经不能满足我们的需求,这里我们就需要一个会动的进度条,效果如下图所示。
  光效进度条主要是做了一个进度动画,在已完成的部分上进行快速的迭代渲染,给用户一种直观感受,我们的软件一直努力加载,它还活着。
  有了这个进度条之后,当我们的进度从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、延迟到达进度条
  动效进度条可能更适用于启动界面,但是也有一些时候,我们可能需要更平缓的一个加载曲线,例如安装软件、卸载软件的时候。
  【领QT开发教程 学习资料,点击下方链接莬费领取↓↓ ,先码住不迷路~】「链接」
  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、背景图等等
  【领QT开发教程 学习资料,点击下方链接莬费领取↓↓ ,先码住不迷路~】「链接」
  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、绘制程序logoQPainter 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 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);

2022中国药品市场全域零售报告医药电商增速将超20数以亿计的国人,正在指尖探索一个线上的健康中国。中康CMH近日发布的2022中国药品市场全域零售报告(以下简称报告)显示,2022年实体药房市场(包含O2O)增速将达5。2,电商B为什么银行要收员工的护照?你永远不知道银行人员能搞出多大的金额。十几年前,银行普通员工转走全县农民的三千万补贴出逃。20多年前,某国有大行的县级支行长(科级干部),卷走4。8亿美金(北京朝阳区4000套房)出入境政策优化出境机票量升价跌入境机票量价齐涨出入境政策优化后,民航市场出现冰火两重天的局面。12月27日,在关于对新型冠状病毒感染实施乙类乙管的总体方案发布后,多家旅游平台机票搜索量大增,但由于往来国际航班数量仍未完全恢复,出入境政策调整,国际机票海外目的地搜索量暴涨湖南日报新湖南客户端12月27日讯(记者刘涛)12月26日晚,国家卫健委网站发布关于对新型冠状病毒感染实施乙类乙管的总体方案(以下简称方案),对疫情防控出入境政策进行了调整。受此影马刺三人20,主场126122力克爵士在今日的常规赛中,马刺主场126122力克爵士。马刺在前三节逐步扩大领先优势,第三节3分41秒时布兰汉姆三分命中,马刺领先达到20分。克拉克森连续得分缩小分差,三节过后爵士以829小型纯电动SUV怎么选?浅析顶配版启辰e30首年用车成本买车要考虑自己的经济条件,根据自己的收入水平选择适合自己的车型。对于很多工薪阶层来说,月收入五六千元,在生活成本的支出上就已经捉襟见肘了。所以在考虑买车时,除了新车的售价之外,用车数字藏品渐成Z世代追风者心头所好2022年卡塔尔世界杯期间,众多世界杯主题数字藏品如雨后春笋破土而出。如FIFA创世NFT(数字藏品)系列数藏中国世界杯国宝系列数字藏品灵境藏品kickoff系列等等。随着区块链技入门卡发布1年还要1799元起!RTX3050偷偷变心功耗节省15WNVIDIA此前曾为RTX3070Ti更换核心,从完整的GA104变成残血的GA102。没想到,入门级的RTX3050也来了一波类似的操作。日前更新的GPUZ2。52。0版本,就曾鸿蒙3。0上配置NFC碰一碰最近更新了HarmonyOS3。0系统,按照过去的方法配置NFC碰一碰方法配置应用,发现出现了一些问题,在一些摸索测试中总结了一套最新最简洁的配置方法。本次为之前的遥控器应用,配置特朗普,第892位美国前总统特朗普已经宣布竞选下届美国总统。特朗普还有多少钱,这些钱能否成为他参加2024年总统大选的助力,成为美国媒体关注的话题。据福布斯杂志12月26日报道,截至今年9月,特朗普21世纪板块构造转载中国科学地球科学板块构造学说在21世纪经历了从大陆漂移到海底扩张和板块俯冲的发展历程。通过梳理有关研究进展发现,岩石圈与软流圈之间沿板块边缘在物质运动能量传递动力体制和低温梯度
新港区李建华督导新竣工新投产项目12月12日,新港区党工委书记李建华前往部分重点项目现场督导。红网时刻岳阳12月13日讯(通讯员刘克宏)年终在即,全年工作进入冲刺期。2022年城陵矶新港区一批新竣工新投产项目运行iPhone伪装定位GPS修改大师TenorshareiAnyGo你是不是想玩PokmonGO这类LBSAR模式的游戏?是不是不能四处踩点打卡?答案是NO!其实可以透过修改iPhoneGPS定位这个公开的秘法来解决。要做到iPhone伪装定位的方重温甄嬛传,甄嬛2次小产皇上态度大不同,5个动作对比心酸头条创作挑战赛11年后再次看甄嬛传,其中,甄嬛曾经有过2次小产,一次是刚进宫不久,表面被华妃罚跪所害,实际是因为安陵容给她在舒痕胶里面下了麝香。第二次是从甘露寺回宫后,为了扳倒皇后清朝官员紫禁城骑马是怎么回事?历史书籍或者近年流行的宫廷戏中,经常出现紫禁城骑马一语。紫禁城是众所周知的皇帝住所和朝廷办公场所,怎么可能让人随随便便在里面骑马溜达呢?其实,紫禁城骑马在古代是一种很高的政治待遇呢一图读懂关于进一步降低制度性交易成本更大激发市场主体活力的若干措施为进一步深化放管服改革,持续优化营商环境助力稳定宏观经济大盘。近日,市政府办公厅印发了关于进一步降低制度性交易成本更大激发市场主体活力的若干措施,围绕市场主体开办运营发展的全过程,监控易火星版纳管IPv6IP地址管理V2。0的进化之路IPv6的使用,不仅能解决网络地址资源数量的问题,而且也解决了多种接入设备连入互联网的障碍。大量IP地址的接入,导致运维人员不得不投入大量精力来解决IP管理分散非法接入IP地址错误中国手机知难而进开拓韩国市场韩国的手机卖场(图片来自网络)每当和韩国朋友谈起开放的议题时,他们总是自夸韩国是多么地民主自由,甚至还列举出一大堆事实。比如选举制度言论自由土地私有等等。其实,从一般人的认知水平来锡安库里的三分球毫无意义,正在毁掉篮球的对抗性,应取消三分锡安做客美国杨毅的一档活动中,对现在的NBA制度非常不满,锡安库里的三分球真的让人无语,根本没带来篮球的进步,而是正在毁掉篮球的对抗及激情的意义,我感觉应该是时候取消三分,当队员手新买的固态硬盘无法开机?最近政府发放了数字人民币消费券,我有幸也抽中了,100元减58元。想想其他也没啥好买了,旧电脑的固态硬盘还是256Gsata的,现在固态也便宜了很多,于是就狗东入手了一块西数的sn年底换新机就选华为Mate50系列,硬核配置智慧体验耐用且实用眼看就到一年一度的双十二年终购物季了,相信很多朋友都计划趁此良机为自己或家人入手一台新手机。可以看到,现如今智能手机早已成为我们绝大多数人日常使用需求和频次最高的电子设备,无论是移玩HiFi,第一套音响怎么选才划算?常听人说道摄影穷三代,HIFI毁一生。这一论调颇为吓人,让许多想购置音响套装的音乐爱好者瑟瑟发抖,买贵的亏空钱包,买便宜的又怕不靠谱,无比纠结,迟迟不敢入手一套改善听音条件的音响。