上一期我们大致实现了布局等操作
那么这一期我们来实现如何去搜索歌曲:
首先呢,我们是设计多媒体,要包含多媒体类头文件,还要能在线搜索,那就要包含网络上的头文件,还要实现打开文件操作,处理文本块,计时器等操作,我们要加上头文件。
不过再加上头文件之前,要在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()函数从一个QString或QByteArray类型的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);
}
代码运行结果:
感谢阅读!!!!!