代码地址:GitHub
文档与提交记录章节相同,方便查看代码变动。视频教学里的酷狗api已经无法使用,自己摸索了一下,还学到了点爬虫知识。教学视频是我废了好大劲搞来的,三连+关注点赞评论进入个人博客领取啦
1 新建项目
新建项目,为Qwidget
新建res文件,去网上找点图标放入
1.1 UI设计
按下图设计ui也可以自己设计,美观我暂时就不考虑了只要实现功能
添加播放进度条,播放的其他按钮,声音调节进度条
1.2 修改背景
自定义一个paintEvent(),把图片画到界面上就行,我还是不用背景了,哈人
void OnlineMp3Widget::paintEvent(QPaintEvent *event)
{QPainter painter(this);painter.drawPixmap(0,0,width(),height(),QPixmap(":/res/dinyilang.png"));
}
1.3 生成所有控件的槽函数
按钮只需要点击槽函数,声音大小调节的进度条需要值变化的槽函数
播放音乐进度条需要,这三个槽函数
最后就是这么多槽函数
1.4 添加必要库和头文件
在.pro文件添加必要库,network multimedia sql
添加必要的头文件
#include <QNetworkRequest> //HTTP的URL管理类
#include <QNetworkAccessManager> //URL的上传管理
#include <QNetworkReply> //网页回复数据触发信号的类
#include <QEventLoop> //提供一种进入和离开事件循环的方法
#include <QJsonArray> //封装JSON数组
#include <QJsonObject> //封装JSON对象#include <QMediaPlayer> //播放音乐相关
#include <QMediaPlaylist>#include <QSqlDatabase> //数据库相关
#include <QSqlQuery>
#include <QSqlError>#include <QMessageBox>
#include <QTime>
#include <math.h>
2 部分逻辑编写
2.1关闭窗口
在ui界面右击关闭按钮,转到槽,使用click事件,编写代码后我们就可以点击按钮关闭界面
void OnlineMp3Widget::on_btn_close_clicked()
{this->close();
}
2.2 鼠标拖动窗口
定义三个函数,点击移动释放,两个变量。
当鼠标左键按下时,把mousePress
标志为真,计算鼠标相对于窗口左上角的偏移量,储存在movePoint
中;当鼠标移动时获取鼠标的全局位置,并计算移动距离,通过move函数将窗口移动到新位置
//移动事件
void OnlineMp3Widget::mouseMoveEvent(QMouseEvent *event)
{if (mousePress) // 如果鼠标被按下{QPoint movepos = event->globalPos(); // 获取鼠标当前的全局位置move(movepos - movePoint); // 移动窗口位置}
}//鼠标释放事件
void OnlineMp3Widget::mouseReleaseEvent(QMouseEvent *event)
{Q_UNUSED(event) // 避免未使用的参数警告mousePress = false; // 鼠标释放,标记鼠标状态为未按下
}//鼠标点击事件
void OnlineMp3Widget::mousePressEvent(QMouseEvent *event)
{if (event->button() == Qt::LeftButton) // 如果鼠标左键被按下{mousePress = true; // 标记鼠标状态为按下}movePoint = event->globalPos() - pos(); // 计算鼠标相对于窗口左上角的偏移量
}
3 歌曲数据库搭建,歌曲搜索
3.1 数据库搭建
首先连接数据库,如果不存在的话创建一个数据库
// 1、连接数据库,如果不存在则创建if (QSqlDatabase::contains("song")) // 检查是否存在名为"song"的数据库连接{db = QSqlDatabase::database("song"); // 如果存在,则获取该数据库连接}else{db = QSqlDatabase::addDatabase("QSQLITE"); // 如果不存在,则添加一个SQLite数据库连接db.setDatabaseName("song.db"); // 设置数据库文件名为"song.db"}
使用open打开数据库,使用query作为查询语句,创建歌曲信息表格,表里边有id,歌名,歌手,
// 2、打开数据库,读取数据表if (!db.open()) // 尝试打开数据库{// 打开数据库失败,显示错误信息QMessageBox::critical(nullptr, "错误", db.lastError().text());}else{// 3、定义查询对象,执行数据库操作QSqlQuery query; // 定义数据库查询对象QString qstl = "create table if not exists songlist(id integer , songname text , singername text , album_id text)"; // 创建歌曲列表表格的SQL语句int ret = query.exec(qstl); // 执行SQL语句if (!ret) // 检查SQL执行是否成功{// SQL执行失败,显示错误信息QMessageBox::critical(nullptr, "错误", db.lastError().text());qDebug() << db.lastError();}
创建歌曲记录表格,用于我们搜索后记录,双击后又能再次播放
// 创建歌曲记录表格qstl = "create table if not exists songhistory(id integer primary key autoincrement, songname text , singername text)";ret = query.exec(qstl);if (!ret){QMessageBox::critical(nullptr, "错误", db.lastError().text());}
通过record将搜索记录显示在ListWidget上
// 查询歌曲历史记录表中的数据并显示qstl = "select * from songhistory";if (!query.exec(qstl)) // 执行查询操作{// 查询失败,显示错误信息QMessageBox::critical(nullptr, "错误", db.lastError().text());}while (query.next()) // 遍历查询结果{QString songname, singername;QSqlRecord rec = query.record(); // 获取查询结果的记录int songnamekey = rec.indexOf("songname"); // 获取歌曲名字段在查询结果中的索引int singerkey = rec.indexOf("singername"); // 获取歌手名字段在查询结果中的索引songname = query.value(songnamekey).toString(); // 获取歌曲名singername = query.value(singerkey).toString(); // 获取歌手名QString strshow = songname + "--" + singername; // 构造要显示的字符串QListWidgetItem *item = new QListWidgetItem(strshow); // 创建列表项ui->lw_record->addItem(item); // 添加列表项到列表控件中}
3.2 搜索歌曲并且双击播放
3.2.1点击搜索on_btn_search_clicked
在我们在搜索框输入歌曲名时,首先需要清空搜索队列,并且删除sonlist数据表中的所有数据;根据歌曲名称,使用酷狗的api构建网络搜索的URL;调用httpAccess函数发起http响应,使用loop等待http请求结束,一旦完成finish信号发出,数据将会储存在JsonData中。
static QString kugouSearchApi = "http://mobilecdn.kugou.com/api/v3/search/song?";
static QString kugouDownldadApi = "https://wwwapi.kugou.com/yy/index.php?";
void OnlineMp3Widget::on_btn_search_clicked()
{// 清空搜索队列ui->lw_learch->clear();// 清理数据库中已经存储的 hash 等数据QSqlQuery query;QString sql = "delete from songlist;" ;if(!query.exec(sql)){QMessageBox::critical(nullptr,"错误",query.lastError().text());}// 根据用户输入的 MP3 名称发起操作请求QString url = kugouSearchApi + QString("format=json&keyword=%1&page=1&pagesize=20&showtype=1").arg(ui->le_search->text());// 发起 HTTP 请求httpAccess(url);QByteArray JsonData;QEventLoop loop;// 等待 HTTP 请求完成并获取数据auto c = connect(this, &OnlineMp3Widget::finish, [&](const QByteArray &data){JsonData = data;loop.exit(1);});loop.exec();disconnect(c);// 解析获取的 JSON 数据hashJsonAnalysis(JsonData);
}
3.2.2 发送网页请求httpAccess
编写httpAccess函数。首先实例化网络请求,将URL存入,创建一个管理对象manger,用manger发送get请求,查看manger的类里边有完成的信号,使用改信号绑定槽函数netReplay
void OnlineMp3Widget::httpAccess(QString url)
{//实例化网络请求操作事项request = new QNetworkRequest;//将url网页地址存入request请求中request->setUrl(url);//实例化网络管理(访问)manager = new QNetworkAccessManager;//通过get,上传具体的请求manager->get(*request);//当网页回复消息,出发finish信号,读取数据connect(manager,&QNetworkAccessManager::finished,this,&OnlineMp3Widget::netReplay);
}
3.2.3 读取网络数据netReplay
使用attribute获得响应的状态码,状态码用于指示服务器对请求的处理结果,例如 200 表示请求成功。如果没有发生错误,读取数据并且发送finish信号
// 读取网络数据槽函数
void OnlineMp3Widget::netReply(QNetworkReply *reply)
{// 获取响应状态码,200 属于正常QVariant status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);qDebug() << status_code;// 重定向目标属性reply->attribute(QNetworkRequest::RedirectionTargetAttribute);if (reply->error() == QNetworkReply::NoError){// 如果没有发生网络错误,则读取响应数据QByteArray data = reply->readAll();// 发射自定义的 finish 信号,将响应数据传递给槽函数emit finish(data);}else{// 如果发生了网络错误,则打印错误信息qDebug() << reply->errorString();}
}
3.2.4 解析网页回复数据并存储hashJsonAnalysis
首先我们先打印一下json看看长啥样,把json保存下来打开查看
QFile file("output.json");if(file.open(QIODevice::WriteOnly | QIODevice::Text)){file.write(JsonData);file.close();}
可以发现我们需要的数据在data-info-[编号]里边,因此我们要进到里边去读取数据
进入data-info-[序号],读取歌名,歌手名,hash,专辑,存入搜索数据表,并且把歌曲名和歌手名作为item展示在界面上
// 将 JSON 数据解析为 QJsonDocument 对象QJsonDocument document = QJsonDocument::fromJson(JsonData);if(document.isObject()) // 如果解析后的对象是一个 JSON 对象{QJsonObject data = document.object(); // 获取 JSON 对象中的"data"字段if(data.contains("data")) // 如果"data"字段存在{QJsonObject objectInfo = data.value("data").toObject(); // 获取"data"字段中的对象if(objectInfo.contains("info")) // 如果"info"字段存在{QJsonArray objectHash = objectInfo.value("info").toArray(); // 获取"info"字段中的数组for(int i = 0; i < objectHash.count(); i++) // 遍历数组中的每个元素{QString songname, singername, album_id, hash;QJsonObject album = objectHash.at(i).toObject(); // 获取数组元素中的对象// 从对象中获取歌曲名、歌手名、专辑 ID 和哈希值if(album.contains("album_id")){album_id = album.value("album_id").toString();}if(album.contains("songname")){songname = album.value("songname").toString();}if(album.contains("singername")){singername = album.value("singername").toString();}if(album.contains("hash")){hash = album.value("hash").toString();}// 将解析出的信息插入数据库QSqlQuery query;QString sql = QString("insert into songlist values(%1,'%2','%3','%4','%5')").arg(QString::number(i)).arg(songname).arg(singername).arg(album_id).arg(hash);if(!query.exec(sql)) // 如果插入数据库失败{QMessageBox::critical(nullptr, "插入数据库错误", db.lastError().text());}// 在搜索展示框中显示歌曲名称和歌手名称QString show = songname + " " + singername;QListWidgetItem *item = new QListWidgetItem(show);ui->lw_search->addItem(item);}}}}
运行程序搜索后发现报错,插入数据库报错,查看发现数据库只有4个title,而我插入有5个,少了个hash,修改前边代码,添加上hash表头
再次运行发现不报错,也可以显示信息了
4 歌曲下载播放,修改新的酷狗搜索下载api
4.1 歌曲下载和播放downloadPlayer
构建下载歌曲的url,发起http请求,等待完成并获取数据,musicJsonAnalysis解析Json获取要播放的文件url
// 音乐歌曲的下载和播放
void OnlineMp3Widget::downloadPlayer(QString album_id, QString hash)
{// 构建下载歌曲的 URLQString url = kugouDownldadApi + QString("r=play/getdata""&hash=%1&album_id=%2""&dfid=1spkkh3QKS9PeiJupz0oTy5G""&mid=de94e92794f31e9cd6ff4cb309d2baa2""&platid=4").arg(hash).arg(album_id);// 发起 HTTP 请求获取歌曲数据httpAccess(url);QByteArray JsonData;QEventLoop loop;// 等待 HTTP 请求完成并获取数据auto d = connect(this, &OnlineMp3Widget::finish, [&](const QByteArray &data){JsonData = data;loop.exit(1);});loop.exec();disconnect(d);// 解析要播放的音乐QString music = musicJsonAnalysis(JsonData);// 设置媒体并播放音乐player->setMedia(QUrl(music));// 设置音量player->setVolume(50);// 设置音量滚动条ui->hs_sound->setValue(50);// 播放音乐player->play();
}
4.2 解析歌曲歌词json文件musicJsonAnalysis
首先也是先下载一下json看一下里边的格式,我们需要进入data字段获取lyrics和play_url。发送显示歌词信号,返回播放地址url
// 解析 JSON 数据,获取音乐播放 URL
QString OnlineMp3Widget::musicJsonAnalysis(QByteArray JsonData)
{// 保存 JSON 数据到文件中以便查看QFile file("download.json");if (file.open(QIODevice::WriteOnly | QIODevice::Text)){file.write(JsonData);file.close();}// 解析 JSON 数据QJsonDocument document = QJsonDocument::fromJson(JsonData);if (document.isObject()){QJsonObject data = document.object();if (data.contains("data")){QJsonObject objectPlayurl = data.value("data").toObject();// 如果包含歌词,发送歌词显示信号if (objectPlayurl.contains("lyrics")){emit lyricShow(objectPlayurl.value("lyrics").toString());}// 返回音乐播放 URLif (objectPlayurl.contains("play_url")){return objectPlayurl.value("play_url").toString();}}}
}
4.3 双击搜索列表歌曲播放playSearchMusic
双击搜索列表的歌曲,实现播放,先在构造函数里绑定槽函数,查询到QLIstWidegt有这样的一个点击信号,我们就使用它connect(ui->lw_search,&QListWidget::itemClicked,this,&OnlineMp3Widget::playSearchMusic);
点击尝试一下,可以输出行号
//获取双击的歌曲索引,就是数据库的数据表的ID号int row = ui->lw_search->currentRow();qDebug()<<"row"<<row;
随后我们先查询历史记录里有没有这首歌,没有就储存,插入新的数据,然后调用downloadPlayer下载播放歌曲
QSqlQuery query;QString sql = QString("select * from songlist where id = %1;").arg(row);if (!query.exec(sql)){QMessageBox::critical(nullptr, "select * from songlist where id =", db.lastError().text());}// 将选中的音乐的数据信息存入历史数据表QString songname, singername, album_id, hash;while (query.next()){QSqlRecord record = query.record();int songkey = record.indexOf("songname");int singerkey = record.indexOf("singername");int albumkey = record.indexOf("album_id");int hashkey = record.indexOf("hash");songname = query.value(songkey).toString();singername = query.value(singerkey).toString();album_id = query.value(albumkey).toString();hash = query.value(hashkey).toString();// 查询历史数据表中是否已经存在该歌曲的记录sql = QString("select hash from songhistory where hash = '%1'").arg(hash);if (!query.exec(sql)){QMessageBox::critical(nullptr, "select hash from songhistory where hash =", db.lastError().text());}// 如果不存在该记录,则将其存入历史数据表if (query.next() == NULL){sql = QString("insert into songhistory values(NULL, '%1', '%2', '%3', '%4')").arg(songname).arg(singername).arg(album_id).arg(hash);if (!query.exec(sql)){QMessageBox::critical(nullptr, "insert error", db.lastError().text());}// 将歌手和歌名放入历史歌曲表中显示QString show = songname + " " + singername;QListWidgetItem *item = new QListWidgetItem(show);ui->lw_record->addItem(item);}}// 下载并播放选中的音乐downloadPlayer(album_id, hash);
4.4 双击没有声音
但是此时运行双击歌曲,发现有报错,插入hash报错了。原来是我新建历史表格的数不对,表头只有歌名和歌手,所以插入报错了。修改后再次运行,双击无报错,但没有声音。
排查发现获取到的download的Json数据有问题,可能是api失效了。
发现歌词和播放地址现在都存在这里边
他的链接形式
https://wwwapi.kugou.com/play/songinfo?srcappid=2919&clientver=20000&clienttime=1713771570169&mid=707708a817d80eedd95f2ae68bc57780&uuid=707708a817d80eedd95f2ae68bc57780&dfid=11SITU3au0iw0OdGgJ0EhTvI&appid=1014&platid=4&encode_album_audio_id=j5yn384&token=&userid=0&signature=59068ffba4652d7eb4868a460db73375
对比两首不同得歌,这三个参数不一样,而且现在hash已经没用了,使用的是encode_album_audio_id
clienttime
:时间戳
encode
:音乐
signature
:md5加密参数
主要是signature这个参数,找到他,打开代码来源
打上断点刷新页面运行几步代码,发现也就是这些信息组合后加密得到signature
4.4.1 安装openssl(可以不装,没用到)
要使用md5加密的库需要安装openssl,我们直接下载安装版https://slproweb.com/products/Win32OpenSSL.html,下载64位的安装包
这一步我们选择放到bin
打开cmd,输入openssl version,显示版本,安装成功
4.4.2 md5加密函数实现
就是把网页上的所有字符串都拼起来然后进行加密
QString OnlineMp3Widget::getMd5(QString time, QString encode_album_audio_id)
{// 构建签名列表QStringList signature_list;signature_list << "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt"<< "appid=1014"<< "clienttime=" + time<< "clientver=20000"<< "dfid=11SITU3au0iw0OdGgJ0EhTvI"<< "encode_album_audio_id=" + encode_album_audio_id<< "mid=707708a817d80eedd95f2ae68bc57780"<< "platid=4"<< "srcappid=2919"<< "token="<< "userid=0"<< "uuid=707708a817d80eedd95f2ae68bc57780"<< "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt";// 将签名列表中的元素连接成一个字符串QString string = signature_list.join("");//qDebug()<< string;//生成 MD5 哈希QByteArray hashedData = QCryptographicHash::hash(string.toUtf8(), QCryptographicHash::Md5);// 将哈希数据转换为十六进制字符串QString md5Hash = hashedData.toHex();return md5Hash;
}
同时需要修改酷狗api
static QString kugouDownldadApi = "https://wwwapi.kugou.com/play/songinfo?";//构建下载歌曲的 URLQDateTime time = QDateTime::currentDateTime();// 将当前时间转换为自纪元以来的秒数,并将其转换为字符串QString currentTimeString = QString::number(time.toSecsSinceEpoch()*1000);currentTimeString = "1713782920612";QString encode_album_audio_id = "j5yn384";QString signaturecode = getMd5(currentTimeString,encode_album_audio_id);QString url = kugouDownldadApi + QString("srcappid=2919""&clientver=20000""&clienttime=%1""&mid=707708a817d80eedd95f2ae68bc57780""&uuid=707708a817d80eedd95f2ae68bc57780""&dfid=11SITU3au0iw0OdGgJ0EhTvI""&appid=1014""&platid=4""&encode_album_audio_id=%2""&token=""&userid=0""&signature=%3").arg(currentTimeString).arg(encode_album_audio_id).arg(signaturecode);
手动输入网页的时间和歌曲id,进行测试看看md5加密对不对,发现能够对上,并且也能够播放音乐了
4.5 hash已经没用了,替换为encode_album_audio_id,修改搜索歌曲函数
hash已经是老的apil,现在使用encode_album_audio_id即可,我们回到搜索歌曲的Json里,发现没有那个id,所以要自己重新搜索加入。在酷狗的搜索界面我们找到了这个id,把他取出。
对比发现更下载歌曲的变化相同,仿照着上边来写
更改酷狗搜索apihttps://complexsearch.kugou.com/v2/search/song?
,修改搜索歌曲
//搜索歌曲
void OnlineMp3Widget::on_btn_search_clicked()
{// 清空搜索队列ui->lw_search->clear();// 清理数据库中已经存储的 hash 等数据QSqlQuery query;QString sql = "delete from songlist;" ;if(!query.exec(sql)){QMessageBox::critical(nullptr,"错误",query.lastError().text());}QDateTime time = QDateTime::currentDateTime();// 将当前时间转换为自纪元以来的秒数,并将其转换为字符串QString currentTimeString = QString::number(time.toSecsSinceEpoch()*1000);QString signaturecode = getSearch_Md5(ui->le_search->text(),currentTimeString);// 根据用户输入的 MP3 名称发起操作请求QString url = kugouSearchApi + QString("callback=callback123""&srcappid=2919""&clientver=1000""&clienttime=%1""&mid=707708a817d80eedd95f2ae68bc57780""&uuid=707708a817d80eedd95f2ae68bc57780""&dfid=11SITU3au0iw0OdGgJ0EhTvI""&keyword=%2""&page=1""&pagesize=30""&bitrate=0""&isfuzzy=0""&inputtype=0""&platform=WebFilter""&userid=0""&iscorrection=1""&privilege_filter=0""&filter=10""&token=""&appid=1014""&signature=%3").arg(currentTimeString).arg(ui->le_search->text()).arg(signaturecode);// 发起 HTTP 请求httpAccess(url);QByteArray JsonData;QEventLoop loop;// 等待 HTTP 请求完成并获取数据auto c = connect(this, &OnlineMp3Widget::finish, [&](const QByteArray &data){JsonData = data;loop.exit(1);});loop.exec();disconnect(c);// 解析获取的 JSON 数据hashJsonAnalysis(JsonData);
}
打断点跟上边一样,发现要输入这些数据,进行md5的编码
QString OnlineMp3Widget::getSearch_Md5(QString songname, QString time)
{// 构建签名列表QStringList signature_list;signature_list << "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt"<< "appid=1014"<< "bitrate=0"<< "callback=callback123"<< "clienttime=" + time<< "clientver=1000"<< "dfid=11SITU3au0iw0OdGgJ0EhTvI"<< "filter=10"<< "inputtype=0"<< "iscorrection=1"<< "isfuzzy=0"<< "keyword=" + songname<< "mid=707708a817d80eedd95f2ae68bc57780"<< "page=1"<< "pagesize=30"<< "platform=WebFilter"<< "privilege_filter=0"<< "srcappid=2919"<< "token="<< "userid=0"<< "uuid=707708a817d80eedd95f2ae68bc57780"<< "NVPh5oo715z5DIWAeQlhMDsWXXQV4hwt";// 将签名列表中的元素连接成一个字符串QString string = signature_list.join("");//qDebug()<< string;//生成 MD5 哈希QByteArray hashedData = QCryptographicHash::hash(string.toUtf8(), QCryptographicHash::Md5);// 将哈希数据转换为十六进制字符串QString md5Hash = hashedData.toHex();return md5Hash;
}
4.6 修改数据库和其他相关代码
先手动删除数据库中的两个表,修改搜索数据库(代码改动较多,可以查看提交)
修改完后运行,查看hashjson,拿到EMixSongID,要进入data-list-EMixSongID
修改代码,发现Json前边有callback123(),识别不了,需要把这个callback123和外边的一对括号删了,找到括号的下标,提取出中间的Json
//移除callback123()// 找到第一个左括号 "(" 的位置int leftBracketIndex = JsonData.indexOf('(');if (leftBracketIndex != -1){// 找到最后一个右括号 ")" 的位置int rightBracketIndex = JsonData.lastIndexOf(')');if (rightBracketIndex != -1){// 提取 JSON 数据,去除包裹的部分JsonData = JsonData.mid(leftBracketIndex + 1, rightBracketIndex - leftBracketIndex - 1);}}
修改下边读取Json,读取FileName,EMixSongID
// 将 JSON 数据解析为 QJsonDocument 对象QJsonDocument document = QJsonDocument::fromJson(JsonData);if(document.isObject()) // 如果解析后的对象是一个 JSON 对象{qDebug()<<"boject";QJsonObject data = document.object(); // 获取 JSON 对象中的"data"字段if(data.contains("data")) // 如果"data"字段存在{QJsonObject objectInfo = data.value("data").toObject(); // 获取"data"字段中的对象qDebug()<<"data";if(objectInfo.contains("lists")) // 如果"lists"字段存在{QJsonArray objectHash = objectInfo.value("lists").toArray(); // 获取"lists"字段中的数组qDebug()<<"lists";for(int i = 0; i < objectHash.count(); i++) // 遍历数组中的每个元素{QString singer_song_name,EMixSongID;QJsonObject album = objectHash.at(i).toObject(); // 获取数组元素中的对象// 从对象中获取歌曲名、歌手名、专辑 ID 和哈希值if(album.contains("FileName")){singer_song_name = album.value("FileName").toString();}if(album.contains("EMixSongID")){EMixSongID = album.value("EMixSongID").toString();}// 将解析出的信息插入数据库QSqlQuery query;QString sql = QString("insert into songlist values(%1,'%2','%3');").arg(QString::number(i)).arg(singer_song_name).arg(EMixSongID);if(!query.exec(sql)) // 如果插入数据库失败{QMessageBox::critical(nullptr, "插入数据库错误", db.lastError().text());}// 在搜索展示框中显示歌曲名称和歌手名称QListWidgetItem *item = new QListWidgetItem(singer_song_name);ui->lw_search->addItem(item);}}}}
再次运行,搜索列表能够显示歌曲
4.7 修复双击播放歌曲playSearchMusic
代码与新的数据库对应即可
// 将选中的音乐的数据信息存入历史数据表QString singer_song_name,EMixSongID;while (query.next()){QSqlRecord record = query.record();int singer_song_namekey = record.indexOf("FileName");int EMixSongIDkey = record.indexOf("EMixSongID");singer_song_name = query.value(singer_song_namekey).toString();EMixSongID = query.value(EMixSongIDkey).toString();// 查询历史数据表中是否已经存在该歌曲的记录sql = QString("select EMixSongID from songhistory where EMixSongID = '%1';").arg(EMixSongID);if (!query.exec(sql)){QMessageBox::critical(nullptr, "select hash from songhistory where EMixSongID =", db.lastError().text());}// 如果不存在该记录,则将其存入历史数据表if (query.next() == NULL){sql = QString("insert into songhistory values(NULL, '%1', '%2')").arg(singer_song_name).arg(EMixSongID);if (!query.exec(sql)){QMessageBox::critical(nullptr, "insert error", db.lastError().text());}// 将歌手和歌名放入历史歌曲表中显示QListWidgetItem *item = new QListWidgetItem(singer_song_name);ui->lw_record->addItem(item);}}// 下载并播放选中的音乐downloadPlayer(EMixSongID);
}
5 歌词显示,进度条
5.1 歌词显示
点击访问博客查看更多内容 |
---|