QT音乐播放器⑦----堆叠轮播图、PathView动态效果堆叠轮播图
简介:
基于QT5.12版本的Quick QML项目----恋羽音乐播放器(爆肝中......)
上一讲链接:https://blog.csdn.net/2301_80668528/article/details/151934834
ps:如有错误,欢迎指出^\/^
原视频出处:https://b23.tv/gFnMsLg
一、堆叠轮播图
1.创建组件化轮播图
右键MusicIconButton.qml文件->"Duplicate"(复制)

命名为:“MusicBannerView.qml”->"OK"

创建完成:

删除原有内容(import模块除外)
2.放入Item{},编辑内容:
注意:播图本质上是图片的的显示,所以需要用到Image{}组件
MusicBannerView.qml中的代码如下:
import QtQuick 2.12
import QtQuick.Controls 2.5
Item
{
property int current: 0 //当前下标
property var bannerList: []
/* 轮播图组中靠左侧的图片 */
MusicRoundImage
{
id:leftImage
width: parent.width * 0.8
height: parent.height
anchors
{
left: parent.left
bottom: parent.bottom
bottomMargin: 20 //左侧图片底部与父类底部的间距
}
imgSrc: getLeftImgSrc()
}
/* 轮播图组中中心位置的图片 */
MusicRoundImage
{
id:centerImage
width: parent.width * 0.8
height: parent.height
z: 2 //垂直与屏幕的坐标定位
anchors.centerIn: parent //定位在父类中心位置
imgSrc: getCenterImgSrc()
}
/* 轮播图组中靠右侧的图片 */
MusicRoundImage
{
id:rightImage
width: parent.width * 0.8
height: parent.height
anchors
{
right: parent.right
bottom: parent.bottom
bottomMargin: 20 //右侧图片底部与父类底部的间距
}
imgSrc: getRightImgSrc()
}
/****** 获取轮播图路径ImgSrc的函数begin ******/
/* 获取轮播图最左侧图片的函数 */
function getLeftImgSrc()
{
//“+ bannerList.length”再“% bannerList.length”是为了避免current = 0的情况下数组bannerList下标变成 -1
return bannerList.length ? bannerList[(current - 1 + bannerList.length) % bannerList.length].imageUrl : ""
}
/* 获取轮播图中心位置图片的函数 */
function getCenterImgSrc()
{
//如果bannerList.length > 0,就返回bannerList[current]
return bannerList.length ? bannerList[current].imageUrl : ""
}
/* 获取轮播图最右侧图片的函数 */
function getRightImgSrc()
{
return bannerList.length ? bannerList[(current + 1+ bannerList.length) % bannerList.length].imageUrl : ""
}
/****** 获取轮播图路径ImgSrc的函数end ******/
}
3.调用组件
打开DetialRecommendPageView.qml文件,导入模块:
import QtQuick.Layouts 1.3 //布局
修改布局,使用ScrollView{}布局(允许用户在有限的屏幕空间内滚动查看更多的内容):

在顶部文本显示区域之下添加轮播图:

传递bannerList数据:
将main.qml文件中的网络请求部分剪贴进DetialRecommendPageView.qml文件中:


替换两个“testHttp()”为“getBannerList()”:

改为->

删除第39行打印输出代码:

在onReply()函数中加入以下代码:
JSON.parse(reply)
原因:localhost:3000/banner中的数据是JSON类型的,需要转化成String类型
创建新变量banners,件转化后的数据存入其中(第49行):

添加轮播图id:

将数据通过轮播图 id 传给bannerList:
bannerView.bannerList = banners

此时可能会有如图所示报错:
需要点击QtCreater左上角“构建”->"清理项目",来清除一下缓存:

Ctrl+R:报错解决
ps:也可能出现如下错误:
qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed
qrc:/MusicRoundImage.qml:11:5: QML Image: TLS initialization failed
测试问题:
在main.cpp文件中包含头文件:
#include <QSslSocket>
#include <QDebug>
在主程序中添加代码行:
qDebug() << "OpenSSL Version:" << QSslSocket::sslLibraryBuildVersionString();
qDebug() << "Supports SSL:" << QSslSocket::supportsSsl();
重新运行,如果如果 supportsSsl() 返回 false,说明当前环境缺少 OpenSSL 支持:

解决办法:
从 OpenSSL 官方网站 下载适合您系统架构(32 位或 64 位)的 OpenSSL 动态库:
找到对应的版本,比如我的版本是刚刚打印的1.1.1,同时,也要注意工程是32位还是64位,我这里选择的是Win64 OpenSSL v1.1.1n Light,至于EXE还是MSI都没差异

下载完成:

右键,以管理员身份运行:

勾选第一个“accept”选项->“Next”:

选择默认安装路径->"Next":

勾选第二个选项“The OpenSSL binaries(/bin) directory”->"Next",方便的进行dll文件的拷贝:

->"Install":

->"finished":

打开下载目录,拷贝以下两个文件到 Qt 安装目录下的bin文件中:
复制:

粘贴(如我现在粘贴到的路径是E:\QT\QT5_14_2\5.14.2\mingw73_32\bin):

重新运行程序,Ctrl+R:

调整左右两侧轮播图的宽高比例:
width: parent.width * 0.6
height: parent.height * 0.8
运行发现轮播图左右两端与父组件之间没有间距:

解决方式:将Item{}改成Frame{}(Frame组件默认带一个边框,有边间距):

在PageHomeView文件中添加以下代码,使轮播图两侧间距相等:
spacing: 0
shift+Delete删除console.log()所在行,Ctrl+R:

将中央图片宽度系数改成0.6:
width: parent.width * 0.6
Ctrl+R:

4.轮播效果实现
实现轮播图图片的切换通常有两种方式:
①点击左右两侧图片进行切换;
②使用轮播图下面的indicator
(1)现在先用第①种方式----点击左右两侧图片进行切换实现:
需要创建鼠标点击事件, 使用MouseArea{}:
点击左侧图片:
/* 点击左测图片进行切换 */
MouseArea
{
anchors.fill: parent
onClicked:
{
if(bannerList.length > 0)
{
//判断current是否为0,不为0就自减
current = current == 0 ? bannerList.length - 1 : current - 1
}
}
}
点击右侧图片:
/* 点击右侧图片进行切换 */
MouseArea
{
anchors.fill: parent
onClicked:
{
if(bannerList.length > 0)
{
//判断current是否为bannerList.length - 1,不为就自增
current = current == bannerList.length - 1 ? 0 : current + 1
}
}
}
Ctrl+R:
轮播图测试效果①
此效果可明显看出轮播图在图片切换时会比较卡顿
(2)用第②种方式----使用轮播图下面的indicator:

Ctrl+R:

点击轮播图下方刚刚设置的indicator就能实现图片间的切换
设置Frame{}的背景色为透明色:

再写一个鼠标进入轮播图时鼠标呈手指指示型的函数:

在Frame{}中添加MouseArea{}:

同时,在图片切换中也设置鼠标形状:
左边图片:

中心图片:

右边图片:

Ctrl+R,鼠标进入轮播图区域时成功变成了手指指示型
5.自动切换图片
包含Timer所需的模块:
import QtQml 2.12
定义一个Timer:

Ctrl+R运行:
轮播图测试效果②
6.鼠标点击轮播图时,轮播图组切换停止
将Timer{}中的 id:imageTimer改成bannerTimer:

在MouseArea中开启hover(悬停)、添加onEntered{}代码:
hoverEnabled: true //悬停
onEntered: //鼠标进入
{
bannerTimer.stop() //停止图片轮播
}
onExited:
{
bannerTimer.start //继续轮播
}

7.当鼠标悬停在indicator上时,中央图片切换到对应图片
在PageIndicator{}的delegate:Rectangle{}中添加MouseArea{}:

Ctrl+R,测试结果符合预期
8.添加图片切换动画
在三个MusicRoundImage{}中分别加入代码:
//左侧图片动画
/* 图片切换动画 */
onImgSrcChanged: //当图片路径改变时
{
leftImageAnim.start() //开始动画
}
NumberAnimation
{
id: leftImageAnim
target: leftImage
property: "scale" //目标对象缩放比例
from: 0.8 //缩放比例从0.8开始
to: 1.0 //缩放比例到1.0结束
duration: 200 //动画持续时间:200ms
}
//中央图片动画
/* 图片切换动画 */
onImgSrcChanged: //当图片路径改变时
{
centerImageAnim.start() //开始动画
}
NumberAnimation
{
id: centerImageAnim
target: centerImage
property: "scale" //目标对象缩放比例
from: 0.8 //缩放比例从0.8开始
to: 1.0 //缩放比例到1.0结束
duration: 200 //动画持续时间:200ms
}
//右侧图片动画
/* 图片切换动画 */
onImgSrcChanged: //当图片路径改变时
{
rightImageAnim.start() //开始动画
}
NumberAnimation
{
id: rightImageAnim
target: rightImage
property: "scale" //目标对象缩放比例
from: 0.8 //缩放比例从0.8开始
to: 1.0 //缩放比例到1.0结束
duration: 200 //动画持续时间:200ms
}
Ctrl+R,测试即可看到缩放动画效果
9.美化顶部文本栏
进入DetialRecommendPageView.qml文件:
修改font.pointSize为25,加入新的Rectang{},将Text{}放入Rectangle中:

将其他的Detialxxxxxxx.qml文件也进行以上修改
Ctrl+R,实现效果:

二、PathView动态效果堆叠轮播图
1.另起工程文件
复制工程MusicPlayer_V2_0,将原工程命名为MusicPlayer_V2_1,新工程命名为MusicPlayer_V2_2:

PathView动效堆叠轮播图将在MusicPlayer_V2_2中继续实现
打开新工程MusicPlayer_V2_2:
2.删除原有代码
删除MusicBannerView.qml文件中除背景外的原有代码:

3.PathView制作轮播图
在DetialRecommendPageView.qml文件中导入以下模块:
import QtQml 2.12
进入MusicBannerView.qml文件:
添加PathView{},并在其中添加delegate{},添加路径Path{}:
PathView
{
id: bannerView
width: parent.width
height: parent.height
clip: true //可滚动页面,多余部分自动裁剪
delegate:Item
{
id: delegateItem
width: bannerView.width * 0.7
height: bannerView.height
z: PathView.z
scale: PathView.scale
MusicRoundImage
{
id: image
imgSrc: modelData.imageUrl
width: delegateItem.width
height: delegateItem.height
}
}
pathItemCount: 3 //当前展示的View里面有3个Item
path: bannerPath
}
Path
{
id: bannerPath
startX: 0
startY: bannerView.height / 2
PathAttribute{name: "z"; value: 0}
PathAttribute{name: "scale"; value: 0.6}
PathLine //直线
{
x: bannerView.width / 2
y: bannerView.height / 2
}
PathAttribute{name: "z"; value: 2}
PathAttribute{name: "scale"; value: 0.85}
PathLine //直线
{
x: bannerView.width
y: bannerView.height / 2
}
PathAttribute{name: "z"; value: 0}
PathAttribute{name: "scale"; value: 0.6}
}
说明:
①在QML中,Delegate是一种非常重要的组件,特别是在使用ListView、GridView、PathView等视图组件时。Delegate用于定义每个列表或网格中的项目是如何展示的。通过自定义Delegate,可以控制每个项目的外观和行为。
②PathAttribute放在某个路径段的前面,指明这段路径起始时的属性值;路径段后面的 PathAttribute 指明路径段终止时的属性值;而在路径段上的属性值, Path 会根据起、止值自动插值计算。
③Path:PathView 的专有特性,它指定 PathView 用来放置 item 的路径
修改bannerList的数据类型为“alias”,并赋值给bannerView.model:

Ctrl+R运行,效果如下:
轮播图测试效果③
发现:没有让中间的图片居中,下面用highlight强调来进行居中
4.强调中间图片
在PathView{}添加preferredHighlight属性:

Ctrl+R运行,效果如下:
轮播图测试效果④
5.添加轮播图底部indicator
在Path{}后面添加PageIndicator{}并设置其属性:
/* 底部Indicator */
PageIndicator
{
id: indicator
anchors
{
top: bannerView.bottom
horizontalCenter: parent.horizontalCenter //水平居中
}
count: bannerView.count
currentIndex: bannerView.currentIndex //设置下标
spacing: 10 //子元素之间的间距
delegate: Rectangle
{
width: 15
height: 5
radius: 5
color: index === bannerView.currentIndex ? "black" : "gray"
/* 动画效果 */
Behavior on color
{
ColorAnimation
{
duration: 200
}
}
/* 鼠标悬停在某indicator上时,切换至对应的图片 */
MouseArea
{
anchors.fill: parent
hoverEnabled: true //启用悬停
onEntered:
{
bannerView.currentIndex = index //使用下标操作图片的切换
}
onExited:
{
}
}
}
}
Ctrl+R运行:
轮播图测试效果⑤
测试发现:虽然图片能正常随着鼠标悬停而切换,但鼠标如果不是按左右顺序挨个悬停,就会报以下错误:

原因:PathAttribute{}在计算时发生了错误
解决方式:对delegate:Item{}中的scale和z值进行判断(给下图中29~30行加上判断):

Ctrl+R重新运行,报错解决
6.点击左右侧图片时切换图片
在delegate:Item{}中添加以下代码:
/* 点击左右侧图片时切换图片 */
MouseArea
{
anchors.fill: parent
cursorShape: Qt.PointingHandCursor //切换鼠标形状
onClicked:
{
if(bannerView.currentIndex === index)
{
}
else
{
bannerView.currentIndex = index
}
}
}
修改路径起点坐标,使轮播图位置靠上一点:

并在PageIndicator{}的anchors定位中添加顶部边缘间距:
topMargin: -10 //与顶部边缘的间距
7.添加自动轮播功能
添加定时器Timer{}:
/* 自动轮播定时器 */
Timer
{
id:bannerTimer
running: true
repeat: true
interval: 3000 //轮播图片切换间隔时间:3s
onTriggered:
{
if(bannerView.count > 0)
{
bannerView.currentIndex = (bannerView.currentIndex + 1) % bannerView.count
}
}
}
在PageIndicator{}中,触发MouseArea{}鼠标进入事件onEntered:{}时,将定时器停止;鼠标退出onExited:{}时,定时器继续计时:
分别调用以下接口:
bannerTimer.stop()
bannerTimer.start()

在PathView中同样添加鼠标进出对应的定时器止、启效果:

设置轮播图的透明背景色:

Ctrl+R:

至此,QT Quick QML项目音乐播放器第七部分----堆叠轮播图、PathView动态效果堆叠轮播图完结,感谢您的阅读!
更多推荐



所有评论(0)