简介:

基于QT5.12版本的Quick QML项目----恋羽音乐播放器(爆肝中......)

上一讲链接:https://blog.csdn.net/2301_80668528/article/details/151934834

下一讲链接:https://blog.csdn.net/2301_80668528/article/details/152420929?fromshare=blogdetail&sharetype=blogdetail&sharerId=152420929&sharerefer=PC&sharesource=2301_80668528&sharefrom=from_link

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是一种非常重要的组件,特别是在使用ListViewGridViewPathView等视图组件时。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{}中的scalez值进行判断(给下图中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动态效果堆叠轮播图完结,感谢您的阅读!

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐