Qt打造音乐播放器

Qt C++ 打造音乐播放器

一、写在前面

这次我使用Qt C++编写的一款音乐播放器,通过网络获得qq音乐曲库的音乐,进行播放。这个程序的名称为泠然Music_0.1,第一个版本,这个版本只实现了单曲播放。环境:VS 2017+Qt 5.12 Win10系统。

二、写在中间

1、新建Qt项目

Qt打造音乐播放器Qt打造音乐播放器Qt打造音乐播放器

2、整体结构

Qt打造音乐播放器
(1)Music.h

class Music : public QWidget
{
	Q_OBJECT
public:
	Music(QWidget *parent = Q_NULLPTR);
	~Music();
	void setWidget();							//窗口界面设置
	void setConnection();						//信号槽连接设置
	void analyseJson();							//json字符串分析
	void mousePressEvent(QMouseEvent *event);	//鼠标点击事件
	void mouseMoveEvent(QMouseEvent *event);	//鼠标移动事件
protected  slots:
	void searchActClicked();					//查询action事件
	void startRequest();						//http请求完毕后处理函数
	void setUrl(QString);						//url设置
	void about();								//关于
	void preBtnClicked();						//前一首按钮事件
	void playBtnClicked();						//播放按钮事件
	void nextBtnClicked();						//下一首
	void quitClicked();							//退出
	void setSlider();							//进度条设置
private:
	Ui::MusicClass			*ui;
	QPushButton				*preBtn;			//上一首按钮
	QPushButton				*nextBtn;			//下一首按钮
	QPushButton				*pauseBtn;			//播放按钮
	QLineEdit				*searchLEdit;		//搜索按钮
	QAction					*searchAct;			//搜索action
	QSlider					*slider;			//进度条
	QNetworkAccessManager	*manager;			//网络请求,响应管理
	QNetworkReply			*reply;				//网络响应
	
	QSystemTrayIcon          *trayIcon;			//托盘按钮
	QMenu                    *trayMenu;			//托盘按钮右键菜单
	QAction                  *quitAction;		
	QAction                  *aboutAction;
	QUrl                     url;
	QString                  resultJson;
	QIcon                    icon;
	QMediaPlayer             *player;			//媒体对象
	bool				     playState;			//播放状态
	QPoint                   offset;
};

(2)Music.cpp
Qt打造音乐播放器
Qt打造音乐播放器
①构造函数,界面的一些控件对象

Music::Music(QWidget *parent)
	: QWidget(parent),ui(new Ui::MusicClass)
{
	ui->setupUi(this);
	this->url = "";												
	this->resultJson = "";
	this->icon = QIcon(":/image/Music.png");		
	this->playState = false;				
	this->preBtn = new QPushButton(this);	
	this->nextBtn = new QPushButton(this);
	this->pauseBtn = new QPushButton(this);
	this->searchLEdit = new QLineEdit(this);
	this->searchAct = new QAction(this);
	this->slider = new QSlider(Qt::Horizontal, this);
	this->manager = new QNetworkAccessManager(this);
	this->trayIcon = new QSystemTrayIcon(this);
	this->trayMenu = new QMenu(this);
	this->quitAction = new QAction(this);
	this->aboutAction = new QAction(this);
	this->setFixedSize(330,90);
	this->setWidget();
	this->setConnection();
	this->player = new QMediaPlayer(this);
}

②setWidget():用于设置界面

void Music::setWidget()
{
	this->setWindowIcon(this->icon);						//设置图标,任务栏中的图标
	this->setWindowFlags(Qt::FramelessWindowHint);  //将标题栏删去,即没有关闭,最小化按钮,也无法移动
	this->preBtn->setIcon(QIcon(":/image/left-circle.png"));
	this->pauseBtn->setIcon(QIcon(":/image/play-circle.png"));
	this->nextBtn->setIcon(QIcon(":/image/right-circle.png"));
	this->searchAct->setIcon(QIcon(":/image/search.png"));
	this->preBtn->setIconSize(QSize(30, 40));
	this->pauseBtn->setIconSize(QSize(30, 40));
	this->nextBtn->setIconSize(QSize(30, 40));
	this->preBtn->setStyleSheet("QPushButton{border:none;}");
	this->pauseBtn->setStyleSheet("QPushButton{border:none;}");
	this->nextBtn->setStyleSheet("QPushButton{border:none;}");
	this->searchLEdit->setStyleSheet("border-radius:15px;border-width:5px");
	this->slider->setStyleSheet("  \
     QSlider::add-page:Horizontal\
     {     \
        background-color: rgb(87, 97, 106);\
        height:4px;\
     }\
     QSlider::sub-page:Horizontal \
    {\
        background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:1, y2:0, stop:0 rgba(231,80,229, 255), stop:1 rgba(7,208,255, 255));\
        height:4px;\
     }\
    QSlider::groove:Horizontal \
    {\
        background:transparent;\
        height:6px;\
    }\
    QSlider::handle:Horizontal \
    {\
        height: 30px;\
        width:8px;\
        margin: -8 0px; \
    }\
    ");

	this->searchLEdit->setPlaceholderText(tr("搜索歌曲"));
	this->searchLEdit->setClearButtonEnabled(true);
	this->searchLEdit->setTextMargins(2, 0, 0, 0);
	this->searchLEdit->setFont(QFont("宋体",14,QFont::Bold));
	this->searchLEdit->setGeometry(QRect(QPoint(10, 10),QPoint( 200, 50)));
	this->preBtn->setGeometry(QRect(QPoint(210, 10), QPoint(240, 50)));
	this->pauseBtn->setGeometry(QRect(QPoint(250, 10), QPoint(280, 50)));
	this->nextBtn->setGeometry(QRect(QPoint(290, 10), QPoint(320, 50)));
	this->slider->setGeometry(QRect(QPoint(10, 60), QPoint(320, 70)));
	this->searchLEdit->addAction(this->searchAct, QLineEdit::TrailingPosition);
	this->aboutAction->setIcon(QIcon(":/image/info-circle.png"));
	this->aboutAction->setText("关于");
	this->quitAction->setIcon(QIcon(":/image/close-circle.png"));
	this->quitAction->setText("退出");
	this->trayIcon->setIcon(this->icon);				//系统托盘图标
	this->trayMenu->addAction(this->aboutAction);  //右键图标显示的菜单
	this->trayMenu->addSeparator();
	this->trayMenu->addAction(this->quitAction);
	this->trayIcon->setContextMenu(this->trayMenu);
	this->preBtn->setEnabled(false);
	this->nextBtn->setEnabled(false);
	this->pauseBtn->setEnabled(false);
}

大概就是下面这个样子
Qt打造音乐播放器
Qt打造音乐播放器
Qt打造音乐播放器
③setConnection():设置信号槽的连接

void Music::setConnection()
{
	connect(this->searchAct, &QAction::triggered, this, &Music::searchActClicked);
	//当请求访问结束后,转向另一个函数。
	connect(this->manager, &QNetworkAccessManager::finished, this, &Music::startRequest);
	connect(this->quitAction, &QAction::triggered, this, &Music::quitClicked);
	connect(this->aboutAction, &QAction::triggered, this, &Music::about);
	connect(this->preBtn, &QPushButton::clicked, this, &Music::preBtnClicked);
	connect(this->pauseBtn, &QPushButton::clicked, this, &Music::playBtnClicked);
	connect(this->nextBtn, &QPushButton::clicked, this, &Music::nextBtnClicked);
}

④searchActClicked():这个函数是搜索action的点击事件

void Music::searchActClicked()
{
	QString songName = this->searchLEdit->text();
	this->setUrl(songName);			//处理url
	//以get方式向服务器请求访问
	this->reply = this->manager->get(QNetworkRequest(this->url));
}

⑤startRequest():manager以get方式发送请求完毕时处理接收到的信息

void Music::startRequest()
{
	//读取接收到的信息
	this->resultJson = this->reply->readAll();
	//对接收到的信息进行分析,得到我们需要的信息
	this->analyseJson();
	//媒体设置media
	this->player->setMedia(QMediaContent(this->url));
	this->pauseBtn->setEnabled(true);
	//进度条,当媒体内容的进度发生改变,进度条位置也发生相应改变
	connect(this->player, &QMediaPlayer::positionChanged, this, &Music::setSlider);
	this->slider->setValue(0);	
}

⑥setUrl():因为对前端知识不够熟练,而QQ音乐的的代码有点复杂,所以使用的是别人的爬取API,而歌曲名就嵌在请求的URL中,

void Music::setUrl(QString url)
{
	this->url = QString("https://api.bzqll.com/music/tencent/search?key=579621905&s=%1&limit=100&offset=0&type=song").arg(url);
}

⑦about():

void Music::about()
{
	QMessageBox::information(this, "关于", "音乐播放器\n是从QQ音乐曲库中查取并播放。\n Music version 0.1\nby 泠然", "确定");
}

⑧preBtnClicked():暂未实现
⑨nextBtnClicked():暂未实现
⑩playBtnClickde():播放控制按钮

void Music::playBtnClicked()
{
	if (!this->playState)
	{
		this->player->play();
		this->pauseBtn->setIcon(QIcon(":/image/time out.png"));
		this->playState = true;
	}
	else
	{
		this->player->pause();
		this->pauseBtn->setIcon(QIcon(":/image/play-circle.png"));
		this->playState = false;	
	}	
}

⑪quitClicked():关闭事件

void Music::quitClicked()
{
	//QApplication的对象 qApp 
	qApp->quit();
}

⑫setSlider():

void Music::setSlider()
{	
	this->slider->setMaximum(this->player->duration());
	this->slider->setMinimum(0);
	this->slider->setValue(this->player->position());
	if (this->player->position() == this->player->duration())
	{
		this->pauseBtn->setIcon(QIcon(":/image/play-circle.png"));
		this->playState = false;
		this->slider->setValue(0);
		this->player->stop();
		this->pauseBtn->setEnabled(false);
	}
}

⑬analyseJson():解析json

void Music::analyseJson()
{
	QByteArray jsonStr = this->resultJson.toUtf8();
	QJsonDocument jsonDom = QJsonDocument::fromJson(jsonStr);
	QJsonObject rootObj = jsonDom.object();
	if (rootObj.contains("data"))
	{
		QJsonArray dataArray = rootObj.value("data").toArray();
		QJsonObject firstObj = dataArray.at(0).toObject();
		QString url = firstObj.value("url").toString();
		this->url = url;
	}
}

⑬mousePressEvent():鼠标点击事件

void Music::mousePressEvent(QMouseEvent * event)
{
	if (event->button() == Qt::LeftButton)
	{
		this->offset = event->globalPos() - this->pos();//获得鼠标的位置与窗口的位置之间的差值
	}
}

⑭mouseMoveEvent():鼠标移动事件

void Music::mouseMoveEvent(QMouseEvent * event)
{
	if (event->buttons() == Qt::LeftButton)
	{
		QPoint temp;
		temp = event->globalPos() -this->offset;
		this->move(temp);
	}
}

⑮直接在VS中用Qt写,输入中文时会乱码,需要在头文件中加入几行代码

#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif

三、写在最后

这个程序功能极其单一,只能搜一曲,播一曲;没有任何容错能力,没有判断曲库是否有歌,没有判断输入是否正确,没有判断网络是否连接。所以第一版非常low,后面会更新第二版。