《二》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);
}

代码运行结果:

感谢阅读!!!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值