《二》MP3在线搜索所歌曲的实现

上一期我们大致实现了布局等操作

那么这一期我们来实现如何去搜索歌曲:

首先呢,我们是设计多媒体,要包含多媒体类头文件,还要能在线搜索,那就要包含网络上的头文件,还要实现打开文件操作,处理文本块,计时器等操作,我们要加上头文件。

不过再加上头文件之前,要在Pro文件加上:

QT      +=network
QT      +=multimedia

不然会报错,实现不了

//进行网络访问,获取响应,处理错误等操作
#include<QNetworkAccessManager>
//是上一个发送请求之后,返回的响应类
#include<QNetworkReply>

#include<QMediaPlayer>//添加多媒体播放器的类
#include<QMediaPlaylist>//添加多媒体播放器列表的类
#include<QTextBlock>
#include<QTimer>
#include<QFileDialog>
#include<QJsonParseError>//解析json数据时错误处理类
#include<QJsonObject>//该类用于操作json数组的类
#include<QLCDNumber>

有了头文件之后,我们就应该自定义一些成员变量:

public:
 //自定义成员
    QMediaPlayer *P_PlayerObject;//播放器操作对象
    QMediaPlaylist *P_Playerlist;//定义播放器 列表

    QByteArray QByteArySearchInfo;//存储搜索信息
    QString StrLocalMusicPath;//导入本地音乐路径
    //歌曲id
    int Music_ID;
    int ipos;//标记

    //歌曲名称,歌手
    QString StrMusicName,StrSingerName;
    QTextDocument *docTextObject;//处理富文本内容
    QTextBlock *qTextLine;//处理文本块指针

    QNetworkAccessManager *NetworkAccessManagers;//网络访问

这个标记可以用来标记歌曲的状态等信息,我们先定义着,不够用再接着写,

既然成员变量有了,那我们还缺一些槽函数去处理这些,主要包括进度条的变化,时间的变化,既然是在线 搜索,还要处理返回的数据。

    //自定义槽函数
public slots:
    //处理数据信息返回
    void HandleDataBackFun(QNetworkReply *pReply);
    //处理lcdnumber时间的变化
    void HandleLCDNumberTimeChangeFunc(qint64 duration);
    //处理进度条控件变化
    void HandleProgressTimeChangeFunc(qint64 dration);
    //播放进度位置变化
    void HandlePositionChangeFunc(qint64 position);
    //处理播放歌曲
    void HandlePlaySongFunc();

把这些个槽函数放到cpp文件之后,得去实例化那些个成员变量和槽函数的链接:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //去掉窗口标题栏
    this->setWindowFlags(Qt::FramelessWindowHint);
    //禁止改变窗口大小
    this->setFixedSize(this->width(),this->height());
    //播放进度条控件美化

    //将光标定位到搜索歌曲名称当中
    ui->lineEdit_inputMusic->setFocus();
    //初始化一个实例
    NetworkAccessManagers=new QNetworkAccessManager(this);

    ipos=0;
    docTextObject=ui->plainTextEdit_MusicList->document();
    //设置为只读
    ui->plainTextEdit_MusicList->setReadOnly(true);
    //初始化多媒体实例
    P_Playerlist=new QMediaPlaylist(this);
    P_PlayerObject=new QMediaPlayer(this);
    P_PlayerObject->setMedia(P_Playerlist);//设置播放列表
    //设置播放模式--循环
    P_Playerlist->setPlaybackMode(QMediaPlaylist::Loop);

    //信号与槽
    connect(P_PlayerObject,SIGNAL(positionChanged(qint64)),this,SLOT(HandleLCDNumberTimeChangeFunc(qint64)));
    connect(P_PlayerObject,SIGNAL(positionChanged(qint64)),this,SLOT(HandlePositionChangeFunc(qint64)));
    connect(P_PlayerObject,SIGNAL(positionChanged(qint64)),this,SLOT(HandleProgressTimeChangeFunc(qint64)));
    connect(NetworkAccessManagers,SIGNAL(finished(QNetworkReply*)),this,SLOT(HandleDataBackFun(QNetworkReply*)));
}

初始化这些操作包括了把光标设置在搜索栏中,对富文本的处理也就是 对歌曲列表中的数据进行处理,然后就是当歌曲进度条位置发生改变时,对时间,播放的歌曲等进行槽函数的连接。

我们来逐一击破:

搜索歌曲 :

//搜索歌曲名称
void MainWindow::on_pushButton_serch_clicked()
{
    QString str1,str2;
    str1=ui->lineEdit_inputMusic->text();

    str2="http://music.163.com/api/search/get/web?csrf_token=hlpretag=&hlposttag=&s={"+str1+"}&type=1&offset=0&total=true&limit=1";

    QNetworkRequest networkquest;
    networkquest.setUrl(str2);//将请求的格式给请求对象
    //使用这个类对应的api发送get请求并获取响应数据
    NetworkAccessManagers->get(networkquest);//请求处理
}

搜索歌曲时,我们要定义两个对象,一个用来存储歌曲名称,一个用来去存储搜索这个歌曲的api连接 。然后定义一个网络请求对象去处理str2并获取响应数据。

处理返回数据信息:

处理返回信息我们定义的是:

void HandleDataBackFun(QNetworkReply *pReply);

那我们来实现他:

首先读取到他返回的参数信息。

QByteArySearchInfo=pReply->readAll();

但是如果我们打错了歌曲名称,或者他曲库中没有怎么办呢?

答:我们要定义错误信息来处理他。

QJsonParseError JsonPError;//定义错误信息对象
    //将json文本转换为json对象处理
    QJsonDocument JsonDoc_RecvData=QJsonDocument::fromJson(QByteArySearchInfo,&JsonPError);
    //判断是否符合规则
    if(JsonPError.error!=QJsonParseError::NoError){
        QMessageBox::critical(this,"JsonPError","提示:搜索歌曲格式错误,请重新检查",QMessageBox::Yes);
        return;
    }
QJsonDocument::fromJson(QByteArySearchInfo,&JsonPError);

QJsonDocument是Qt框架提供的用于处理JSON格式数据的类。

在这里,JsonDoc_RecvData是一个QJsonDocument对象,通过QJsonDocument::fromJson()函数从一个QStringQByteArray类型的JSON格式数据中解析出来。其中,QByteArySearchInfo是一个QByteArray类型的JSON格式数据,JsonPError是一个QJsonParseError对象,用于存储解析JSON数据时可能发生的错误信息。如果解析成功,JsonDoc_RecvData将包含JSON数据的所有内容,我们可以通过JsonDoc_RecvData提供的API来访问和操作这些数据。如果解析失败,JsonPError将包含错误信息以及出错位置等相关信息。

//QJsonObject使用函数object()
    QJsonObject JsonTotalObject=JsonDoc_RecvData.object();
    //列出json里面所有的key
    QStringList strKeys=JsonTotalObject.keys();
    if(strKeys.contains("result")){//有数据信息继续
        //将带有result的数据内容提取之后转换为对象
        QJsonObject resultobject=JsonTotalObject["result"].toObject();
        //存储所有的keys
        QStringList strResultKeys=resultobject.keys();
        //如果keys是songs,整明搜索的是歌曲
        if(strResultKeys.contains("songs")){
            QJsonArray jsonarray=resultobject["songs"].toArray();
            //通过for循环查找歌曲当中的字段信息
            for(auto isong:jsonarray){
                QJsonObject jsonobject1=isong.toObject();
                //获取歌曲的id,歌名,歌手
                Music_ID=jsonobject1["id"].toInt();
                StrMusicName=jsonobject1["name"].toString();
                QStringList strkeys=jsonobject1.keys();
                if(strkeys.contains("artists")){
                    QJsonArray artistsjsonarray=jsonobject1["artists"].toArray();
                    for(auto js:artistsjsonarray){
                        QJsonObject jsonobject2=js.toObject();
                        StrSingerName=jsonobject2["name"].toString();
                    }
                }
            }
        }
    }

将JsonDoc_RecvData转化为QJsonObject格式存储到JsonTotalObject中,并通过strKeys获取“关键字”,如果提取到的是result,那么进一步进行提取,直到提取所有的信息,包括歌手,歌曲id等下信息。

 QString strURL;
    strURL=QString("https://music.163.com/song/media/outer/url?id=%0").arg(Music_ID);
    P_Playerlist->addMedia(QUrl(strURL));
    //把搜索到的歌曲和歌手添加到歌曲列表中。
    ui->plainTextEdit_MusicList->appendPlainText(StrMusicName+"-"+StrSingerName);
  • 在这个代码段中,strURL是一个QString类型的对象,通过QString的构造函数将一个字符串常量转换成了一个QString类型的对象,
  • 然后使用arg函数来格式化字符串,将Music_ID的值替换到字符串中的%0处,得到最终的URL地址。
  • 然后,使用QUrl将字符串转换成了一个URL对象,最后通过P_Playerlist->addMedia函数将URL添加到播放列表中。
  • ui->plainTextEdit_MusicList->appendPlainText函数用于将StrMusicName和StrSingerName拼接成一个字符串,并将其添加到文本框中。

完整代码:

void MainWindow::HandleDataBackFun(QNetworkReply *pReply)
{
    //读取网络回馈的数据
    QByteArySearchInfo=pReply->readAll();

    QJsonParseError JsonPError;//定义错误信息对象
    //将json文本转换为json对象处理
    QJsonDocument JsonDoc_RecvData=QJsonDocument::fromJson(QByteArySearchInfo,&JsonPError);
    //判断是否符合规则
    if(JsonPError.error!=QJsonParseError::NoError){
        QMessageBox::critical(this,"JsonPError","提示:搜索歌曲格式错误,请重新检查",QMessageBox::Yes);
        return;
    }
    //QJsonObject使用函数object()
    QJsonObject JsonTotalObject=JsonDoc_RecvData.object();
    //列出json里面所有的key
    QStringList strKeys=JsonTotalObject.keys();
    if(strKeys.contains("result")){//有数据信息继续
        //将带有result的数据内容提取之后转换为对象
        QJsonObject resultobject=JsonTotalObject["result"].toObject();
        //存储所有的keys
        QStringList strResultKeys=resultobject.keys();
        //如果keys是songs,整明搜索的是歌曲
        if(strResultKeys.contains("songs")){
            QJsonArray jsonarray=resultobject["songs"].toArray();
            //通过for循环查找歌曲当中的字段信息
            for(auto isong:jsonarray){
                QJsonObject jsonobject1=isong.toObject();
                //获取歌曲的id,歌名,歌手
                Music_ID=jsonobject1["id"].toInt();
                StrMusicName=jsonobject1["name"].toString();
                QStringList strkeys=jsonobject1.keys();
                if(strkeys.contains("artists")){
                    QJsonArray artistsjsonarray=jsonobject1["artists"].toArray();
                    for(auto js:artistsjsonarray){
                        QJsonObject jsonobject2=js.toObject();
                        StrSingerName=jsonobject2["name"].toString();
                    }
                }
            }
        }
    }
    QString strURL;
    strURL=QString("https://music.163.com/song/media/puter/url?id=%0").arg(Music_ID);
    P_Playerlist->addMedia(QUrl(strURL));
    //把搜索到的歌曲和歌手添加到歌曲列表中。
    ui->plainTextEdit_MusicList->appendPlainText(StrMusicName+"-"+StrSingerName);
}

代码运行结果:

感谢阅读!!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/639428.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

618知识狂欢,挑本好书,点亮智慧生活!

618精选编程书单&#xff1a;提升你的代码力 一年一度的618又到啦&#xff01;今年的618就不要乱买啦&#xff0c;衣服买多了会被淘汰&#xff0c;电子产品买多了会过时&#xff0c;零食买多了会增肥&#xff0c;最后怎么看都不划算。可是如果你购买知识&#xff0c;坚持阅读&a…

k8s节点亲和性配置

在Kubernetes中&#xff0c;你可以使用节点亲和性&#xff08;Node Affinity&#xff09;来控制Pod调度到特定的节点上。节点亲和性是通过Pod的spec.affinity.nodeAffinity属性来设置的。 以下是一个配置节点亲和性的YAML示例&#xff1a; apiVersion: v1 kind: Pod metadata…

nss刷题(3)

1、[SWPUCTF 2021 新生赛]include 根据提示传入一个file后显示了关于flag的代码 这是一个文件包含&#xff0c;考虑php伪协议&#xff0c;构造payload&#xff1a; ?filephp://filter/readconvert.base64-encode/resourceflag.php 2、[SWPUCTF 2021 新生赛]Do_you_know_http …

HTML5 + CSS3模拟庆余年中“五竹”的镭射眼动画特效

庆余年2已经火热开播了&#xff0c;据说反响强烈啊&#xff0c;不知道这一部里面&#xff0c;五竹的镭射眼会不会表现出来&#xff0c;我还挺想看看他的镭射眼的&#xff0c;我看到底有没有杀死剧中的庆帝。 回想第一部&#xff0c;我都快记不清那是几年前开播的了&#xff0c;…

【QT八股文】系列之篇章2 | QT的信号与槽机制及通讯流程

【QT八股文】系列之篇章2 | QT的信号与槽机制及通讯流程 前言2. 信号与槽信号与槽机制介绍/本质/原理&#xff0c;什么是Qt信号与槽机制&#xff1f;如何在Qt中使用&#xff1f;信号与槽机制原理&#xff0c;解析流程Qt信号槽的调用流程信号与槽机制的优缺点信号与槽机制需要注…

明天(周六)下午!武汉Linux爱好者线下沙龙,我们在华中科技大学等你!

2024 年 5月 25 日&#xff08;周六&#xff09;下午&#xff0c;我们将在「武汉市洪山区」 珞喻路 1037 号华中科技大学南五楼 613 室举办武汉 Linux 爱好者线下沙龙&#xff08;WHLUG&#xff09;&#xff0c;欢迎广大 Linux 爱好者来到现场&#xff0c;与我们一同交流技术&a…

【vue echart】完成一个简单echart图表+自适应

实现效果&#xff1a; html&#xff1a; <divref"echartOne"id"echartOne"style"width: 100%; height: 100%" ></div> js: getEchartOne() {let chart this.$echarts.init(this.$refs.echartOne);chart.setOption({title: {text:…

科技产业园3D探秘:未来科技之城的奇幻之旅

在数字时代的浪潮中&#xff0c;科技产业园区成为了推动城市经济发展、科技创新的重要引擎。 当我们打开科技产业园的3D可视化模型&#xff0c;仿佛穿越时空&#xff0c;来到了一个充满奇幻色彩的科技世界。在这里&#xff0c;高楼大厦鳞次栉比&#xff0c;绿色植被点缀其间&am…

Python协程的作用

过分揣测别人的想法&#xff0c;就会失去自己的立场。大家好&#xff0c;当代软件开发领域中&#xff0c;异步编程已成为一种不可或缺的技术&#xff0c;用于处理大规模数据处理、高并发网络请求、实时通信等应用场景。而Python协程&#xff08;Coroutine&#xff09;作为一种高…

数组-区间合并

一、题目描述 二、题目思路 这里提供满足基本要求的解题思路&#xff1a; 1.先对列表内按照start大小升序排序&#xff0c;这里创建Comparator接口的实现类&#xff0c;重写compare方法。 2.遍历intervals&#xff0c;设置laststart、lastend两个变量与当前区间相比较&#…

JavaEE技术之分布式事务(理论、解决方案、Seata解决分布式事务问题、Seata之原理简介、断点查看数据库表数据变化)

文章目录 JavaEE技术之分布式事务准备:1. 本地事务回顾1.1 什么是事务1.2 事务的作用1.3 事务ACID四大特性1.4 事务的并发问题1.5 MySQL事务隔离级别1.6 事务相关命令(了解)1.7 事务传播行为&#xff08;propagation behavior&#xff09;1.8 伪代码练习1.9 回滚策略1.10 超时事…

arcgisPro精确移动要素某一点至指定点位

1、打开要素&#xff0c;如下&#xff1a; 2、选择移动工具&#xff0c;如下&#xff1a; 3、选择需要移动的要素&#xff0c;如下&#xff1a; 4、按住Ctrl键&#xff0c;移动锚点的位置至三角形顶点位置&#xff0c;如下&#xff1a; 5、拖动锚点至上面多边形的左上角点&…

CS西电高悦计网课设——校园网设计

校园网设计 一&#xff0c;需求分析 所有主机可以访问外网 主机可以通过域名访问Web服务器 为网络配置静态或者动态路由 图书馆主机通过DHCP自动获取IP参数 为办公楼划分VLAN 为所有设备分配合适的IP地址和子网掩码&#xff0c;IP地址的第二个字节使用学号的后两位。 二…

K8s资源限制和三种探针

一 默写总结 1 pod 的组成 ① Pod 中有几种容器 init 初始化 &#xff0c;阻塞主容器运行&#xff0c;初始化后方可运行主容器 pause 基础容器&#xff1a; 提供network 的 namespace 和 共享存储 业务容器&#xff1a; 跑Pod 主应用 &#xff08;POD中跑什么&#xff1a;微…

MySQL-性能分析

1、数据库服务器的优化步骤 2、查看系统性能参数 可以使用show status语句查询一些MySQL数据库服务器的性能参数 执行频率语法格式&#xff1a;show [ global | session ] status like 参数 &#xff1b;常用性能参数如下所示 参数名说明connection连接MySQL服务器的次数upti…

某大型制造集团企业信息化建设总体规划设计方案(67页PPT)

方案介绍&#xff1a; 随着信息技术的飞速发展&#xff0c;企业信息化建设已成为提高管理效率、增强企业竞争力的重要手段。某大型制造集团为应对市场变化、提升管理水平、优化资源配置&#xff0c;决定进行全面深入的信息化建设。本方案旨在构建一个集生产、管理、销售、物流…

Linux程序开发(十):文件分类器趣味设计

Tips&#xff1a;"分享是快乐的源泉&#x1f4a7;&#xff0c;在我的博客里&#xff0c;不仅有知识的海洋&#x1f30a;&#xff0c;还有满满的正能量加持&#x1f4aa;&#xff0c;快来和我一起分享这份快乐吧&#x1f60a;&#xff01; 喜欢我的博客的话&#xff0c;记得…

Win10蓝牙鼠标不能移动问题解决

问题描述&#xff1a;鼠标是没损坏的&#xff0c;使用过程中&#xff0c;光标突然就不能移动了&#xff0c;但右键和滚轮还是有反应。 解决&#xff1a; 1&#xff0c;删除蓝牙设置中的如下配置&#xff08;我只使用了无线鼠标&#xff0c;没有无线键盘&#xff09; 2&#x…

智慧校园为高校带来哪些价值

在21世纪的教育图景中&#xff0c;"智慧"不再仅仅是一个科技名词&#xff0c;它已成为衡量教育现代化水平的重要标志。智慧校园&#xff0c;这一融合了物联网、大数据、云计算等先进技术的教育新形态&#xff0c;正逐步成为高校转型升级的关键驱动力。本文将从多个维…

【题解】AB33 相差不超过k的最多数(排序 + 滑动窗口)

https://www.nowcoder.com/practice/562630ca90ac40ce89443c91060574c6?tpId308&tqId40490&ru/exam/oj 排序 滑动窗口 #include <iostream> #include <vector> #include <algorithm> using namespace std;int main() {int n, k;cin >> n &…