上一期我们大致实现了布局等操作
那么这一期我们来实现如何去搜索歌曲:
首先呢,我们是设计多媒体,要包含多媒体类头文件,还要能在线搜索,那就要包含网络上的头文件,还要实现打开文件操作,处理文本块,计时器等操作,我们要加上头文件。
不过再加上头文件之前,要在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;//导入本地音乐路径//歌曲idint 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里面所有的keyQStringList strKeys=JsonTotalObject.keys();if(strKeys.contains("result")){//有数据信息继续//将带有result的数据内容提取之后转换为对象QJsonObject resultobject=JsonTotalObject["result"].toObject();//存储所有的keysQStringList 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里面所有的keyQStringList strKeys=JsonTotalObject.keys();if(strKeys.contains("result")){//有数据信息继续//将带有result的数据内容提取之后转换为对象QJsonObject resultobject=JsonTotalObject["result"].toObject();//存储所有的keysQStringList 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);
}
代码运行结果:
感谢阅读!!!!!