Qt之实现图片轮播效果

article/2025/9/23 23:42:49

一、简述

今天文章讲述的是如何用Qt实现图片轮播的效果,其实我们经常在网页中看到各种广告就是使用了图片轮播,实现小区域内嵌入多个广告的效果。

下面是CSDN页面中两种常见的图片轮播效果。基本上就是定时自动切换广告页面,或者手动点击选择切换页面。

这里写图片描述 这里写图片描述


其实实现起来也不难,只要使用Qt的动画类即可实现类似的效果。之前做了一个,效果不佳,今天重新写了一遍,实现了类似上面第一种的效果,通过Qt的动画类修改透明度来实现上下两张图片的切换效果,下面上效果图。

这里写图片描述 这里写图片描述

二、代码之路

看了上面效果图,大家可以自己心里先思考一下其中实现的原理,如果自己有想法,可以先按照自己的想法实现一遍,然后再来看文章中的代码。如果自己在没看文章代码之前有了更好的实现思路,也可以评论与我一起交流。如果还没想到好的方法可以参考文章中的代码,有问题or有想法call me。

我相信每个人都有自己独特的想法,所以如果一上来就直接看文章中的代码,那么可能错失了一次思考的机会,同时可能失去了一个更好的想法。哈哈,这里也是提一个 个人建议成长之路都是自己一步一步走出来的,也是自己不断思考,不断总结,不断成长才能够在这条路上稳健地走下去

####Tip
实现原理简单梳理一下,主要是提供接口设置图片列表的路径,然后通过动画类来修改图片的透明度来达到切换的动画效果。而图片是直接通过paintEvent事件进行绘制的,同时绘制两张图片,先绘制下一张图片,然后再根据动画类返回的透明度绘制当前图片。图片自动切换通过一个时钟来搞定。也可以手动点击白色小按钮进行图片切换

这里重写了mousePressEvent事件,我们看到web页面上的图片轮播,可以对当前图片进行点击然后触发每个图片对应的效果,一般都是弹出广告页面,这里大家可以根据需求自定义功能。

下面就看一下图片轮播的实现。

CarouselImageWindow.h

#include <QWidget>
#include <QScrollArea>
#include <QTimer>
#include <QPropertyAnimation>
#include <QPushButton>class CarouselImageWindow : public QWidget
{Q_OBJECTpublic:CarouselImageWindow(QWidget *parent = NULL);~CarouselImageWindow();// 设置图片列表;void setImageList(QStringList imageFileNameList);// 添加图片;void addImage(QString imageFileName);// 开始播放;void startPlay();private:// 初始化图片切换按钮;void initChangeImageButton();// 绘图事件;void paintEvent(QPaintEvent *event);// 鼠标点击事件;void mousePressEvent(QMouseEvent* event);public slots:// 图片切换时钟;void onImageChangeTimeout();// 图片切换按钮点击;void onImageSwitchButtonClicked(int buttonId);private:// 用来做图片切换滑动效果,目前以透明度作为切换效果;QScrollArea* m_imagePlayWidget;// 图片列表;QList<QString> m_imageFileNameList;// 图片切换时钟;QTimer m_imageChangeTimer;// 当前显示图片index;int m_currentDrawImageIndx;// 切换图片;QPixmap m_currentPixmap;QPixmap m_nextPixmap;// 图片切换动画类;QPropertyAnimation* m_opacityAnimation;// 按钮列表;QList<QPushButton*> m_pButtonChangeImageList;
};

CarouselImageWindow.cpp

#include "CarouselImageWindow.h"
#include <QHBoxLayout>
#include <QPainter>
#include <QDebug>
#include <QButtonGroup>CarouselImageWindow::CarouselImageWindow(QWidget *parent): QWidget(parent), m_currentDrawImageIndx(0)
{// 添加ImageOpacity属性;this->setProperty("ImageOpacity", 1.0);// 动画切换类;m_opacityAnimation = new QPropertyAnimation(this, "ImageOpacity");// 这里要设置的动画时间小于图片切换时间;m_opacityAnimation->setDuration(1500);// 设置ImageOpacity属性值的变化范围;m_opacityAnimation->setStartValue(1.0);m_opacityAnimation->setEndValue(0.0);// 透明度变化及时更新绘图;connect(m_opacityAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(update()));// 设置图片切换时钟槽函数;connect(&m_imageChangeTimer, SIGNAL(timeout()), this, SLOT(onImageChangeTimeout()));this->setFixedSize(QSize(400, 250));this->setWindowFlags(Qt::FramelessWindowHint);
}CarouselImageWindow::~CarouselImageWindow()
{}void CarouselImageWindow::initChangeImageButton()
{// 注意图片过多按钮可能放置不下;QButtonGroup* changeButtonGroup = new QButtonGroup;QHBoxLayout* hLayout = new QHBoxLayout();hLayout->addStretch();for (int i = 0; i < m_imageFileNameList.count(); i++){QPushButton* pButton = new QPushButton;pButton->setFixedSize(QSize(16, 16));pButton->setCheckable(true);pButton->setStyleSheet("QPushButton{border-image:url(:/Resources/select1.png);}\QPushButton:checked{border-image:url(:/Resources/select2.png);}");changeButtonGroup->addButton(pButton, i);m_pButtonChangeImageList.append(pButton);hLayout->addWidget(pButton);}hLayout->addStretch();hLayout->setSpacing(10);hLayout->setMargin(0);connect(changeButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(onImageSwitchButtonClicked(int)));QVBoxLayout* mainLayout = new QVBoxLayout(this);mainLayout->addStretch();mainLayout->addLayout(hLayout);mainLayout->setContentsMargins(0, 0, 0, 20);
}void CarouselImageWindow::setImageList(QStringList imageFileNameList)
{m_imageFileNameList = imageFileNameList;
}void CarouselImageWindow::addImage(QString imageFileName)
{m_imageFileNameList.append(imageFileName);
}void CarouselImageWindow::startPlay()
{// 添加完图片之后,根据图片多少设置图片切换按钮;initChangeImageButton();if (m_imageFileNameList.count() == 1){m_pButtonChangeImageList[m_currentDrawImageIndx]->setChecked(true);}else if (m_imageFileNameList.count() > 1){m_pButtonChangeImageList[m_currentDrawImageIndx]->setChecked(true);m_currentPixmap = QPixmap(m_imageFileNameList.at(m_currentDrawImageIndx));m_imageChangeTimer.start(2000);update();}   
}void CarouselImageWindow::onImageChangeTimeout()
{// 设置前后的图片;m_currentPixmap = QPixmap(m_imageFileNameList.at(m_currentDrawImageIndx));m_currentDrawImageIndx++;if (m_currentDrawImageIndx >= m_imageFileNameList.count()){m_currentDrawImageIndx = 0;}m_nextPixmap = QPixmap(m_imageFileNameList.at(m_currentDrawImageIndx));m_pButtonChangeImageList[m_currentDrawImageIndx]->setChecked(true);// 动画类重新开始; m_opacityAnimation->start();
}void CarouselImageWindow::paintEvent(QPaintEvent *event)
{QPainter painter(this);QRect imageRect = this->rect();// 如果图片列表为空,显示默认图片;if (m_imageFileNameList.isEmpty()){QPixmap backPixmap = QPixmap(":/Resources/CarouselImageBack.png");painter.drawPixmap(imageRect, backPixmap.scaled(imageRect.size()));}// 如果只有一张图片;else if (m_imageFileNameList.count() == 1){QPixmap backPixmap = QPixmap(m_imageFileNameList.first());painter.drawPixmap(imageRect, backPixmap.scaled(imageRect.size()));}// 多张图片;else if (m_imageFileNameList.count() > 1){float imageOpacity = this->property("ImageOpacity").toFloat();painter.setOpacity(1);painter.drawPixmap(imageRect, m_nextPixmap.scaled(imageRect.size()));painter.setOpacity(imageOpacity);painter.drawPixmap(imageRect, m_currentPixmap.scaled(imageRect.size()));}
}void CarouselImageWindow::onImageSwitchButtonClicked(int buttonId)
{m_currentDrawImageIndx = buttonId - 1;if (m_currentDrawImageIndx == -1){m_currentDrawImageIndx = m_imageFileNameList.count() - 1;}onImageChangeTimeout();m_imageChangeTimer.start(2000);update();
}void CarouselImageWindow::mousePressEvent(QMouseEvent* event)
{// 这里可以对当前图片进行点击然后触发每个图片对应的效果;// 比如web上好多类似的弹出对应的广告页面等功能;qDebug() << m_currentDrawImageIndx;return __super::mousePressEvent(event);
}

测试代码

int main(int argc, char *argv[])
{QApplication a(argc, argv);CarouselImageWindow w;w.addImage(":/Resources/image1.jpg");w.addImage(":/Resources/image2.jpg");w.addImage(":/Resources/image3.jpg");w.addImage(":/Resources/image4.jpg");w.startPlay();w.show();return a.exec();
}

文章到这里也就结束了,此篇文章介绍了通过透明度的方法来实现切换效果,上面提到了另一种滑动效果,这里可以使用QScrollArea来实现类似的效果,如果后面有时间我也会再次详细地介绍如果实现滑动效果。

如需具体工程代码请加左方联系群。


http://chatgpt.dhexx.cn/article/DatqGivi.shtml

相关文章

vue中图片轮播

vue中轮播图的实现 轮播图中html结构一般由主体图片、下方小圆圈、上一张和下一张组成。 主体图片能够实现两秒切换一次&#xff0c;并且对应的小圆圈被选中 点击上一张和下一张按钮切换相应图片&#xff0c;同时小圆圈产生变化。 点击小圆圈切换图片 鼠标放在图片主体上停…

使用transition实现图片轮播效果

前言 无缝轮播一直是面试的热门题目&#xff0c;而大部分答案都是复制第一张到最后。诚然&#xff0c;这种方法是非常标准&#xff0c;那么有没有另类一点的方法呢&#xff1f; 第一种方法是需要把所有图片一张张摆好&#xff0c;然后慢慢移动的&#xff0c; 但是我能不能直…

【JavaScript】常见的几种图片轮播

平时我们会在各种网站看见图片轮播的效果&#xff0c;但它具体是如何实现的呢&#xff1f;接下来咱们一起来看看各种图片轮播效果的产生过程吧&#xff01; 一、图片的无缝滚动 什么是图片的无缝滚动&#xff1f;通俗来讲就是一堆图片一张接着一张往过滑&#xff0c;图片之间没…

实现一个简单的图片轮播效果

学习笔记 思路 这里就说一下我的思路吧&#xff0c;我们可以先将所有图片的不透明度设置为0&#xff0c;也就是全透明&#xff0c;不可见&#xff08;也不一定靠设置透明度来实现图片不可见&#xff0c;也可以直接设置元素不可见&#xff09;&#xff0c;使用下标的方式来控制…

c++ 判断亲和数

c 判断亲和数 在自然数220与284之间&#xff0c;有一种非常奇妙的关系&#xff0c;能够整除22022511的全部正整数&#xff08;不包括220&#xff09;之和1245102011224455110恰好等于284&#xff1b;而能够整除2842271的全部正整数&#xff08;不包括284&#xff09;之和124711…

寻找亲和数对C语言,寻找亲和数

人与人之间讲究友情&#xff0c;而有趣的是&#xff0c;数与数之间也有相类似的关系&#xff0c;数学家把一对存在特殊关系的数称为“亲和数”。亲和数&#xff0c;又称相亲数、友爱数、友好数&#xff0c;指两个正整数中&#xff0c;彼此的全部约数之和(本身除外)与另一方相等…

如何判断亲和数

内容&#xff1a;判断亲和数 目的&#xff1a;掌握循环与if语句 程序代码&#xff1a; /* * 程序的版权和版本声明部分: * Copyright (c) 2013, 烟台大学计算机学院 * All rights reserved. * 文件名称&#xff1a;test.cpp * 作 者&#xff1a;匡效国 …

亲和数-C++

目录 原题目 题目描述: 输入格式: 输出格式: 样例输入: 样例输出: 提示: 解题 part1 part2 part3 原题目 题目描述: 自然数a的因子是指能整除a的所有自然数&#xff0c;但不含a本身。例如12的因子为&#xff1a;1、2、3、4、6。若自然数的因子之和为b&#xff0c;而…

python程序设计——练习9

目录 1.任意整数各个位数之和2.列表下标转换3.稀疏矩阵的表示4.有序列表插入元素5.列表合并去重6.单词的区域7.查验身份证8.亲和数9.乘积的列表10.矩阵相加 1.任意整数各个位数之和 请输入任意一个正整数&#xff0c;求各个位数之和并输出。 输入样例1&#xff1a; 123 输出样…

squeezenet,DSD

squeezenet 2016.11.4 squeezenet的目的是用更少的网络构建模型&#xff0c;同时保持模型的准确率。 出发的三个原则是&#xff1a;1、用1*1卷积代替3*3卷积 2、减少与3*3卷积相连的通道数 3、在网络后期使用采样。保证特征图的大小。 其中1、2的目的是减少参数&#xff0c;同时…

Squid

Squid中文权威指南&#xff1a;点击打开链接 CentOS 6.4下Squid代理服务器的安装与配置 一、简介 代理服务器英文全称是Proxy Server&#xff0c;其功能就是代理网络用户去取得网络信息。 Squid是一个缓存Internet 数据的软件&#xff0c;其接收用户的下载申请&#xff0c;并自…

Squeeze-and excitation network

Squeeze-and excitation network introdutcion motivation&#xff1a;当前一些研究表明&#xff0c;将attention机制引入网络中来捕获特征之间的空间相关性可增强CNN的表征&#xff0c;但本文希望建立channels之间的关系。 整体的SE block的图&#xff1a; 如上图所示&…

SQUIRE: A Sequence-to-sequence Framework for Multi-hop Knowledge Graph Reasoning

摘要 近年来&#xff0c;多跳知识图(KG)推理得到了广泛的研究&#xff0c;以提供具有证据路径的缺失链接的可解释预测。大多数先前的工作使用基于强化学习(RL)的方法来学习导航到目标实体的路径。然而&#xff0c;这些方法的收敛速度慢&#xff0c;收敛性差&#xff0c;当路径…

Squeeze-and-Excitation Networks

摘要 卷积神经网络建立在卷积运算的基础上&#xff0c;通过融合局部感受野内的空间信息和通道信息来提取信息特征。为了提高网络的表示能力&#xff0c;许多现有的工作已经显示出增强空间编码的好处。在这项工作中&#xff0c;我们专注于通道&#xff0c;并提出了一种新颖的架…

HTML页面可视化快速设计

1、HTML页面可视化快速设计工具&#xff1a;Maqetta IBM 公司在 IBM Impact 2011 上面发布了 Maqetta&#xff0c;一个创建桌面和移动用户界面的 HTML5 设计编辑工具&#xff0c;并同时宣布将项目捐助给开源机构 Dojo 基金会。 也即Maqetta 是由 Dojo 基金会提出的开源技术 ,…

HTML 转 EXE 工具(HTML App Build)

2023-07-01 将进行完全功能免费发布&#xff0c;本文中的下载连接已经是最新的下载连接。 2023-02-19 已经进行了重大升级&#xff01; 一款免费的HTML转EXE工具&#xff0c;无论您是单页面应用&#xff0c;或者是其他的使用传统的html javascript css 生成的网站&#xff0c…

HTML5教程|0代码,快速制作调查问卷

我们经常需要收集数据&#xff0c;今天我们来介绍一种自己实现问卷调查数据表的制作方法&#xff0c;本节教程是单选框的交互制作&#xff0c;希望大家看完都可以学会。我们使用的H5工具是Epub360&#xff0c;下面就进入教学环节吧~ 一、组件介绍&#xff1a; 单选项&#xf…

几款制作帮助文档的工具汇总

几款制作帮助文档的工具汇总 文章目录 几款制作帮助文档的工具汇总为什么需要发布产品帮助文档支持在线用 MarkDown格式的编辑器1、[GitBook](https://www.gitbook.com/)2、[Docsify](https://docsify.js.org/)3 、MrDoc4. YDoc5、VuePress6、[Docusaurus](https://docusaurus.…

微软html帮助文档制作,MicrosoftHTMLHelpWorkshop(CHM文件生成工具)

MicrosoftHTMLHelpWorkshop是一款文件制作工具&#xff0c;通过此软件能够帮助我们对CHM文件进行快速编程配置&#xff0c;也可快速的进行建立需要的HYML格式的文件&#xff0c;软件还可单独的进行运行&#xff0c;可快速的制作出CHM文件&#xff0c;简单又实用&#xff0c;有需…

html 制作箭头,怎么使用html制作箭头?制作箭头代码分享!

我们在制作静态页面的时候一般的都会使用一些什么箭头、按钮等等各种形状的控件&#xff0c;但是一般比较常使用的就是用图片加入然后再设置函数从而达到预期的效果&#xff0c;那么今天我们就来说说不用照片怎么设计一个箭头吧&#xff01; 1.编写盒子代码 首先我们使用开发工…