一、功能
1.播放本地音乐
2.添加本地音乐到列表,并播放
3上一曲,下一曲
4.音量控制
5.登录
6.随机播放网络音乐
7进度条控制播放进度
8.音量控制
二、部分功能展示
1.默认主页
打开软件,会展示默认文件夹里的音乐,并把他们放在播放列表里,此时点击播放按钮,默认播放第一首歌曲。
2.播放音乐
点击播放按钮开始播放音乐,而且进度条会随着播放进度改变,用鼠标拖动进度条,放开左键后音乐播放进度会变到进度条所在位置。音量展示的是以当前系统音量为最大值,可以用鼠标拖动,最下面为静音。
3.添加本地音乐
4.随机播放网络歌曲
原打算使用网易云api,登录获取歌曲,但是在获取个人信息时少参数,没找到解决方法,不登录有些歌只能听个试用部分,遂放弃。然后找到一个可以获取随机歌曲的接口,只是该接口返回的信息里,大部分没有名字,所以没有解析歌曲名,直接把链接放在列表里(不是我想偷懒)。
用工具查看内容
{
"msg": "ok",
"res": {
"id": "5b8534b8b02de202d2f97b46",
"anime_info": {
"desc": "\u7a81\u7136\u7684\u591c\u9003\uff0c\u7a81\u7136\u7684\u544a\u767d\uff0c\u7136\u540e\u662f\u7a81\u7136\u7684\u5206\u79bb\u2014\u2014 \u5267\u60c5\u5206\u7c7b\uff1a\u5c11\u5973 \u52b1\u5fd7 \u4e00\u76f4\u4ee5\u6765\u90a3\u4e2a\u60f3\u8981\u53d8\u6210\u4e0d\u540c\u7684\u81ea\u5df1\u7684\u68a6\uff0c\u5ffd\u7136\u5c31\u8fd9\u6837\u6210\u4e86\u771f\u3002 \u6211\uff0c\u677e\u524d\u7eea\u82b1\uff0c\u4e0d\u5e73\u51e1\u751f\u6d3b\u5374\u5728\u4e00\u5929\u4e4b\u5185\u5c45\u7136\u8fce\u6765\u4e86\u7535\u89c6\u8fde\u7eed\u5267\u822c\u7684\u60ca\u4eba\u5c55\u5f00\u3002 \u6211\u5c06\u79bb\u5f00\u8fd9\u4e2a\u719f\u6089\u5374\u6ca1\u4ec0\u4e48\u611f\u60c5\u7684\u57ce\u5e02\uff0c\u524d\u5f80\u672a\u66fe\u8c0b\u9762\u7684\u7956\u6bcd\u5bb6\u751f\u6d3b\u3002 \u90a3\u91cc\u662f\u5145\u6ee1\u4e86\u5927\u6b63\u6d6a\u6f2b\u98ce\u5473\u7684\u6e29\u6cc9\u65c5\u9986\u2014\u2014\u559c\u7fe0\u5e84\u3002 \u5728\u90a3\u91cc\u9047\u5230\u4e86\u5f88\u591a\u4eba\u3002 \u7b80\u76f4\u5c31\u50cf\u82b1\u82bd\u51b2\u7834\u5730\u9762\u8fdb\u5165\u4e86\u4e00\u4e2a\u65b0\u7684\u4e16\u754c\u4e00\u822c\uff0c\u6211\u5f00\u59cb\u4e86\u4e0e\u8fc7\u53bb\u5b8c\u5168\u4e0d\u540c\u7684\u65b0\u7684\u751f\u6d3b\u3002 \u5176\u4e2d\u53ef\u80fd\u4e5f\u6709\u975e\u5e38\u96be\u53d7\u7684\u65f6\u5019\u3002 \u4f46\u662f\uff0c\u4e0d\u7ba1\u53d1\u751f\u4e86\u4ec0\u4e48\uff0c\u660e\u5929\u4f9d\u65e7\u4f1a\u5230\u6765\u30021",
"id": "5b838ab2b02de275deb90f82",
"atime": 1409293698,
"logo": "https://anime-music-files.jijidown.com/img/5b838ab2b02de275deb90f82_logo.jpg",
"year": 2011,
"bg": "https://anime-music-files.jijidown.com/img/5b838ab2b02de275deb90f82_bg.jpg",
"title": "\u82b1\u5f00\u4f0a\u5415\u6ce2(\u82b1\u5f00\u7269\u8bed)",
"month": 4
},
"play_url": "https://anime-music-files.jijidown.com/5b8534b8b02de202d2f97b46_128.mp3?t=1660466972&sign=7D3935976D5DB1394E1F1D31E0F756BB",
"atime": 1535456440,
"title": "Hazy",
"author": "\u672a\u77e5",
"type": "\u5176\u4ed6",
"recommend": false
},
"code": 0
}
解析上面代码,找到需要的url。
void Widget::recv_ack2(QNetworkReply* reply)
{
//首先通过file.readAll()读取为QString字符串
QByteArray buf = reply->readAll(); //获取字节
//qDebug() << buf.toStdString().c_str();
QString result(buf); //转字符串
qDebug()<< result;
//提取json中有用的信息
QByteArray byte_array;
QJsonParseError json_error;
QJsonDocument parse_doucment = QJsonDocument::fromJson(byte_array.append(result), &json_error);
if(json_error.error == QJsonParseError::NoError)
{
if(parse_doucment.isObject())
{
QJsonObject rootObj = parse_doucment.object();
if(rootObj.contains("res"))
{
QJsonValue valuedata = rootObj.value("res");
if(valuedata.isObject())
{
QJsonObject valuedataObject = valuedata.toObject();
QString play_urlStr("");
if(valuedataObject.contains("play_url"))
{
QJsonValue play_url_value = valuedataObject.take("play_url");
if(play_url_value.isString())
{
play_urlStr = play_url_value.toString(); //歌曲的url
qDebug() << play_urlStr;
if(play_urlStr!="")
{
qDebug() << play_urlStr << endl;
//emit mediaAdd(play_urlStr);
//player=new QMediaPlayer; //播放对象
//playList=new QMediaPlaylist; //播放列表对象
QString url; //保存url
//url=QString("https://music.163.com/song/media/outer/url?id=447926067");
//url=QString("https://anime-music-files.jijidown.com/5da8119db186e458444ad9e2_128.mp3?t=1660375237&sign=0286A8914245C2C0141175F8AC1EC988");
url = QString(play_urlStr);
//.arg(musicId); //将音乐ID作为格式输入到url中
mediaPlaylist->addMedia(QUrl(url)); //添加一音乐到播放列表中
musicPlayer->setMedia(mediaPlaylist);
//将列表设置到播放器中
ui->listWidget->addItem(play_urlStr);
//musicPlayer->play();
}
}
}
}
}
}
}
else
{
qDebug()<<json_error.errorString();
}
}
5.登录
该部分接入的是网易云api,如果没理解错误,true应该是登上了,但是继续获取个人信息需要传一个id,这里没有返回给我,其他方式登录又不能用,所以放弃继续用网易云。
三、代码
loginwidget.h
#ifndef LOGINWIDGET_H
#define LOGINWIDGET_H
#include <QWidget>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QJsonParseError>
#include <QJsonDocument>
#include <QJsonObject>
namespace Ui {
class loginWidget;
}
class loginWidget : public QWidget
{
Q_OBJECT
public:
explicit loginWidget(QWidget *parent = 0);
~loginWidget();
private slots:
void on_pushButton_clicked();
void recv_ack(QNetworkReply* r);
void on_pushButton_3_clicked();
void on_pushButton_2_clicked();
//void recv_ack2(QNetworkReply* reply);
private:
Ui::loginWidget *ui;
QNetworkAccessManager *http_acc;
};
#endif // LOGINWIDGET_H
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QSound>
#include <QMediaPlayer>
#include <QMediaPlaylist>
#include <QDir>
#include <QListWidgetItem>
#include "loginwidget.h"
#include <QFileDialog>
#include <QString>
#include <QFileInfo>
namespace Ui {
class Widget;
}
/* 媒体信息结构体 */
struct MediaObjectInfo {
/* 用于保存歌曲文件名 */
QString fileName;
/* 用于保存歌曲文件路径 */
QString filePath;
};
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_sound_button_clicked();
void btn_previous_clicked();
/* 播放按钮点击 */
void btn_play_clicked();
/* 下一曲按钮点击*/
void btn_next_clicked();
/* 媒体列表项改变 在列表中展示当前播放歌曲,即可以随着上一曲,下一曲动*/
void mediaPlaylistCurrentIndexChanged(int);
/* 列表中单击播放*/
void listWidgetCliked(QListWidgetItem*);
/* 媒体总长度改变 显示在标签2中*/
void musicPlayerDurationChanged(qint64);
/* 媒体播放位置改变 显示在标签1中*/
void mediaPlayerPositionChanged(qint64);
/* 播放进度条松开 */
void durationSliderReleased();
/*登录*/
void on_login_clicked();
void recv_ack2(QNetworkReply* reply);
/*随机播放*/
void on_random_clicked();
/*添加音乐*/
void on_addMusic_clicked();
/*控制音量*/
void on_volumeSlider_valueChanged(int value);
private:
Ui::Widget *ui;
/* 媒体信息存储 */
QVector<MediaObjectInfo> mediaObjectInfo;
/* 媒体播放器,用于播放音乐 */
QMediaPlayer *musicPlayer;
/* 媒体列表 */
QMediaPlaylist *mediaPlaylist;
/* 用于遮罩 */
QWidget *listMask;
/* 扫描歌曲 */
void scanSongs();
/* 媒体播放器类初始化 */
void mediaPlayerInit();
/*按钮设置*/
void buttonInit();
QNetworkAccessManager *http_acc2;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPalette>
#include <QPixmap>
#include <QBrush>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
http_acc2 = new QNetworkAccessManager;
/* 媒体播放器初始化 */
mediaPlayerInit();
/* 扫描歌曲 */
scanSongs();
/*设置按钮图标*/
buttonInit();
ui->listWidget->setFrameShape(QListWidget::NoFrame);
/* 按钮信号槽连接 */
connect(ui->btn_previous, SIGNAL(clicked()),this, SLOT(btn_previous_clicked()));
connect(ui->btn_play, SIGNAL(clicked()),this, SLOT(btn_play_clicked()));
connect(ui->btn_next, SIGNAL(clicked()),this, SLOT(btn_next_clicked()));
/* 媒体信号槽连接 */
//connect(musicPlayer, SIGNAL(stateChanged(QMediaPlayer::State)), this,SLOT(mediaPlayerStateChanged(QMediaPlayer::State)));
connect(mediaPlaylist, SIGNAL(currentIndexChanged(int)), this, SLOT(mediaPlaylistCurrentIndexChanged(int)));
connect(musicPlayer, SIGNAL(durationChanged(qint64)), this, SLOT(musicPlayerDurationChanged(qint64)));
connect(musicPlayer, SIGNAL(positionChanged(qint64)),this, SLOT(mediaPlayerPositionChanged(qint64)));
/* 列表信号槽连接 */
connect(ui->listWidget, SIGNAL(itemClicked(QListWidgetItem*)),this, SLOT(listWidgetCliked(QListWidgetItem*)));
/* slider 信号槽连接 */
connect(ui->durationSlider, SIGNAL(sliderReleased()),this, SLOT(durationSliderReleased()));
connect(ui->addMusic, SIGNAL(clicked(bool)), this, SLOT(on_addMusic_clicked()));
connect(http_acc2, SIGNAL(finished(QNetworkReply*)), this, SLOT(recv_ack2(QNetworkReply*)));
/*音量控制*/
connect(ui->volumeSlider,SIGNAL(valueChanged(int)),this , SLOT(on_volumeSlider_valueChanged(int)));
/* 失去焦点 */
this->setFocus(); //在播放时,使进度条回到原点
}
Widget::~Widget()
{
delete ui;
}
void Widget::buttonInit()
{
/*设置背景图*/
QPixmap pixmap = QPixmap(":/images/7.jpg").scaled(this->size());
QPalette palette(this->palette());
palette.setBrush(QPalette::Window, QBrush(pixmap));
this->setPalette(palette);
/*设置按钮图标*/
QIcon icon_playButton(":/images/cd.png");
ui->btn_play->setIcon(icon_playButton);
ui->btn_play->setIconSize(QSize(45,45));
ui->btn_play->setFlat(true); //设置图标按钮为透明
ui->btn_play->setStyleSheet("background-color:rgba(0,0,0,0)");
ui->btn_play->setFocusPolicy(Qt::NoFocus); //去除按钮按下时的阴影
QIcon icon_nextButton(":/images/next.png");
ui->btn_next->setIcon(icon_nextButton);
ui->btn_next->setIconSize(QSize(45,45));
ui->btn_next->setFlat(true); //设置图标按钮为透明
ui->btn_next->setStyleSheet("background-color:rgba(0,0,0,0)");
ui->btn_next->setFocusPolicy(Qt::NoFocus); //去除按钮按下时的阴影
QIcon icon_previousButton(":/images/previous.png");
ui->btn_previous->setIcon(icon_previousButton);
ui->btn_previous->setIconSize(QSize(45,45));
ui->btn_previous->setFlat(true); //设置图标按钮为透明
ui->btn_previous->setStyleSheet("background-color:rgba(0,0,0,0)");
ui->btn_previous->setFocusPolicy(Qt::NoFocus); //去除按钮按下时的阴影
QIcon icon_loginButton(":/images/login.png");
ui->login->setIcon(icon_loginButton);
ui->login->setIconSize(QSize(45,45));
ui->login->setFlat(true); //设置图标按钮为透明
ui->login->setStyleSheet("background-color:rgba(0,0,0,0)");
ui->login->setFocusPolicy(Qt::NoFocus); //去除按钮按下时的阴影
ui->btn_volume->setFlat(true); //设置按钮为透明
ui->btn_volume->setStyleSheet("background-color:rgba(0,0,0,0)");
ui->login->setFocusPolicy(Qt::NoFocus); //去除按钮按下时的阴影
ui->addMusic->setFlat(true); //设置按钮为透明
ui->addMusic->setStyleSheet("background-color:rgba(0,0,0,0)");
ui->addMusic->setFocusPolicy(Qt::NoFocus); //去除按钮按下时的阴影
ui->random->setFlat(true); //设置按钮为透明
ui->random->setStyleSheet("background-color:rgba(0,0,0,0)");
ui->random->setFocusPolicy(Qt::NoFocus); //去除按钮按下时的阴影
}
void Widget::mediaPlayerInit()
{
musicPlayer = new QMediaPlayer(this);
mediaPlaylist = new QMediaPlaylist(this);
/* 确保列表是空的 */
mediaPlaylist->clear();
/* 设置音乐播放器的列表为 mediaPlaylist */
musicPlayer->setPlaylist(mediaPlaylist);
/* 设置播放模式,Loop 是列循环 */
mediaPlaylist->setPlaybackMode(QMediaPlaylist::Loop);
}
void Widget::scanSongs()
{
QDir dir(QCoreApplication::applicationDirPath()+ "/myMusic");
QDir dirbsolutePath(dir.absolutePath());
/* 如果目录存在 */
if (dirbsolutePath.exists())
{
qDebug() << "daozhele" << endl;
/* 定义过滤器 */
QStringList filter;
/* 包含所有.mp3 后缀的文件 */
filter << "*.mp3";
/* 获取该目录下的所有文件 */
QFileInfoList files = dirbsolutePath.entryInfoList(filter, QDir::Files);
/* 遍历 */
for (int i = 0; i < files.count(); i++)
{
MediaObjectInfo info;
/* 使用 utf-8 编码 */
QString fileName = QString::fromUtf8(files.at(i).fileName().replace(".mp3", "").toUtf8().data());
info.fileName = fileName + "\n" + fileName.split("-").at(1);
info.filePath = QString::fromUtf8(files.at(i).filePath().toUtf8().data());
/* 媒体列表添加歌曲 */
if (mediaPlaylist->addMedia(QUrl::fromLocalFile(info.filePath)))
{
/* 添加到容器数组里储存 */
mediaObjectInfo.append(info);
/* 添加歌曲名字至列表 */
ui->listWidget->addItem(info.fileName);
} else
{
qDebug()<< mediaPlaylist->errorString().toUtf8().data() << endl;
qDebug()<< " Error number:" << mediaPlaylist->error() << endl;
}
}
}
ui->volumeSlider->setValue(musicPlayer->volume());
}
void Widget::btn_previous_clicked()
{
musicPlayer->stop();
int count = mediaPlaylist->mediaCount();
if (0 == count)
return;
/* 列表上一个 */
mediaPlaylist->previous();
musicPlayer->play();
}
void Widget::on_sound_button_clicked()
{
QSound::play("H:\\NDMdownload\\error.wav");
//error.wav
}
void Widget::btn_play_clicked()
{
int state = musicPlayer->state();
QIcon icon_playButton(":/images/pause.png");
QIcon icon_cdButton(":/images/cd.png");
QIcon icon_pauseButton(":/images/pause.png");
switch (state) {
case QMediaPlayer::StoppedState:
/* 媒体播放 */
musicPlayer->play();
/*设置按钮图标*/
ui->btn_play->setIcon(icon_playButton);
break;
case QMediaPlayer::PlayingState:
/* 媒体暂停 */
musicPlayer->pause();
/*设置按钮图标*/
//QIcon icon_cdButton(":/images/cd.png");
ui->btn_play->setIcon(icon_cdButton);
break;
case QMediaPlayer::PausedState:
musicPlayer->play();
ui->btn_play->setIcon(icon_pauseButton);
break;
}
}
void Widget::btn_next_clicked()
{
musicPlayer->stop();
int count = mediaPlaylist->mediaCount();
if (0 == count)
return;
/* 列表下一个 */
mediaPlaylist->next();
musicPlayer->play();
}
void Widget::mediaPlaylistCurrentIndexChanged(int index)
{
if (-1 == index)
return;
/* 设置列表正在播放的项 */
ui->listWidget->setCurrentRow(index);
}
void Widget::listWidgetCliked(QListWidgetItem *item)
{
musicPlayer->stop();
mediaPlaylist->setCurrentIndex(ui->listWidget->row(item));
musicPlayer->play();
}
void Widget::musicPlayerDurationChanged(qint64 duration)
{
ui->durationSlider->setRange(0, duration / 1000);
int second = duration / 1000;
int minute = second / 60;
second %= 60;
QString mediaDuration;
mediaDuration.clear();
if (minute >= 10)
mediaDuration = QString::number(minute, 10);
else
mediaDuration = "0" + QString::number(minute, 10);
if (second >= 10)
mediaDuration = mediaDuration+ ":" + QString::number(second, 10);
else
mediaDuration = mediaDuration+ ":0" + QString::number(second, 10);
/* 显示媒体总长度时间 */
ui->label_2->setText(mediaDuration);
}
void Widget::mediaPlayerPositionChanged(qint64 position)
{
if (!ui->durationSlider->isSliderDown())
ui->durationSlider->setValue(position/1000);
int second = position / 1000;
int minute = second / 60;
second %= 60;
QString mediaPosition;
mediaPosition.clear();
if (minute >= 10)
mediaPosition = QString::number(minute, 10);
else
mediaPosition = "0" + QString::number(minute, 10);
if (second >= 10)
mediaPosition = mediaPosition+ ":" + QString::number(second, 10);
else
mediaPosition = mediaPosition+ ":0" + QString::number(second, 10);
/* 显示现在播放的时间 */
ui->label->setText(mediaPosition);
}
void Widget::durationSliderReleased()
{
/* 设置媒体播放的位置 */
musicPlayer->setPosition(ui->durationSlider->value() * 1000);
}
void Widget::on_login_clicked()
{
loginWidget *lwidget = new loginWidget ;
lwidget->show();
}
void Widget::recv_ack2(QNetworkReply* reply)
{
//首先通过file.readAll()读取为QString字符串
QByteArray buf = reply->readAll(); //获取字节
//qDebug() << buf.toStdString().c_str();
QString result(buf); //转字符串
qDebug()<< result;
//提取json中有用的信息
QByteArray byte_array;
QJsonParseError json_error;
QJsonDocument parse_doucment = QJsonDocument::fromJson(byte_array.append(result), &json_error);
if(json_error.error == QJsonParseError::NoError)
{
if(parse_doucment.isObject())
{
QJsonObject rootObj = parse_doucment.object();
if(rootObj.contains("res"))
{
QJsonValue valuedata = rootObj.value("res");
if(valuedata.isObject())
{
QJsonObject valuedataObject = valuedata.toObject();
QString play_urlStr("");
if(valuedataObject.contains("play_url"))
{
QJsonValue play_url_value = valuedataObject.take("play_url");
if(play_url_value.isString())
{
play_urlStr = play_url_value.toString(); //歌曲的url
qDebug() << play_urlStr;
if(play_urlStr!="")
{
qDebug() << play_urlStr << endl;
//emit mediaAdd(play_urlStr);
//player=new QMediaPlayer; //播放对象
//playList=new QMediaPlaylist; //播放列表对象
QString url; //保存url
//url=QString("https://music.163.com/song/media/outer/url?id=447926067");
//url=QString("https://anime-music-files.jijidown.com/5da8119db186e458444ad9e2_128.mp3?t=1660375237&sign=0286A8914245C2C0141175F8AC1EC988");
url = QString(play_urlStr);
//.arg(musicId); //将音乐ID作为格式输入到url中
mediaPlaylist->addMedia(QUrl(url)); //添加一音乐到播放列表中
musicPlayer->setMedia(mediaPlaylist);
//将列表设置到播放器中
ui->listWidget->addItem(play_urlStr);
//musicPlayer->play();
}
}
}
}
}
}
}
else
{
qDebug()<<json_error.errorString();
}
}
void Widget::on_random_clicked()
{
qDebug()<< "随机" <<endl;
QNetworkRequest request;
request.setUrl(QString("https://anime-music.jijidown.com/api/v2/music"));
http_acc2->get(request);
//int state = player->state();
}
void Widget::on_addMusic_clicked()
{
QString filepath = QFileDialog::getOpenFileName(); //弹出一个文件选择对话框,并且返回文件路径
MediaObjectInfo info;
QString fileName;
QFileInfo fileInfo = QFileInfo(filepath);
//文件名
fileName = fileInfo.fileName();
info.fileName = fileName + "\n" ;
info.filePath = filepath;
/* 媒体列表添加歌曲 */
if (mediaPlaylist->addMedia(QUrl::fromLocalFile(info.filePath)))
{
/* 添加到容器数组里储存 */
mediaObjectInfo.append(info);
/* 添加歌曲名字至列表 */
ui->listWidget->addItem(info.fileName);
} else
{
qDebug()<< mediaPlaylist->errorString().toUtf8().data() << endl;
}
}
void Widget::on_volumeSlider_valueChanged(int value)
{
musicPlayer->setVolume(ui->volumeSlider->value());
}
loginwidget.cpp
#include "loginwidget.h"
#include "ui_loginwidget.h"
#include <QSound>
loginWidget::loginWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::loginWidget)
{
ui->setupUi(this);
setWindowTitle("login");
setFixedSize(335,286);
//ui->setScaledContents(ture)
http_acc = new QNetworkAccessManager;
connect(http_acc, SIGNAL(finished(QNetworkReply*)), this, SLOT(recv_ack(QNetworkReply*)));
}
void loginWidget::on_pushButton_clicked()
{
QString str = ui->lineEdit->text();
//QString str2 = ui->lineEdit_2->text();
QNetworkRequest request;
QString str2 = QString("https://netease-cloud-music-api-crete722p-hannah-bingo.vercel.app/captcha/verify?phone=%0&captcha=").arg(ui->lineEdit->text());
QString str3;
str3.append(ui->lineEdit_2->text());
request.setUrl(str3);
qDebug() << str3 << endl;
http_acc->get(request);
}
void loginWidget::on_pushButton_3_clicked()
{
QNetworkRequest request;
request.setUrl(QString("https://netease-cloud-music-api-crete722p-hannah-bingo.vercel.app/captcha/sent?phone=%0").arg(ui->lineEdit->text()));
http_acc->get(request);
}
loginWidget::~loginWidget()
{
delete ui;
}
void loginWidget::on_pushButton_2_clicked()
{
//文件的路径可以是资源文件路径也可以是本地文件系统路径
QSound::play("H:\\NDMdownload\\error.wav");
}
void loginWidget::recv_ack(QNetworkReply* r)
{
QByteArray buf = r->readAll();
qDebug() << buf.toStdString().c_str();
}