本篇开始讲上次说的Qt自制多功能程序功能之一的音乐播放器
![](https://i-blog.csdnimg.cn/blog_migrate/18109e4f2dab365e6e0133d57ff549c8.png)
实现功能
利用数据库,打开音乐播放器自动读取已添加的歌曲,并可以随时添加或删除歌曲;
提供上一首、下一首、暂停/播放、播放方式(单曲循环/随机播放/顺序播放)、音量调节、添加歌曲、删除歌曲按键;
显示当前正在播放的歌曲,并时刻更新进度条以及播放时间;
双击播放列表亦可播放歌曲;
利用qt样式表进行美化。
界面设计(ui)
![](https://i-blog.csdnimg.cn/blog_migrate/371f2c2bddaa3f3a4c9b9178ce4257de.png)
进度条用的也是Qt自带的QSlider,但是原始的QSlider不够美观,这里进行了样式表编辑,如图所示打开样式表
![](https://i-blog.csdnimg.cn/blog_migrate/cccd1f89b8b31e5b1b3b38f387fbde2c.png)
在样式表里添加如下内容,此处将url(:/Image/bool.png)替换为自己的资源图片
QSlider::groove:horizontal {
height: 6px;
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 rgb(124, 124, 124), stop: 1.0 rgb(72, 71, 71));
}
QSlider::handle:horizontal {
border-image: url(:/Image/bool.png);
width: 30px;
height:10px;
margin: -11px px -11px 0px;
}
QSlider::sub-page:horizontal{
background:rgba(255, 85, 127,1);
}
歌曲列表就用QListWidget来显示。
所有按钮都是Qt自带的QPushButton,然后导入的资源图片,并做无边框处理然后放在一个Widget里进行水平布局。无边框处理如下:
*{
border:none;
}
连接数据库
这里我直接用的是qsqlite,这个不用本地安装,qt自带都会有,如果是mysql,需要自己手动进行链接,这里可以用一个函数来查看自己的电脑可以连接到什么数据库,用到数据库之前要现在.pro文件中添加上 QT += sql
QStringList ls = QSqlDatabase::drivers();
qDebug() << ls;
会出现如下信息,说明你可以连接至对应的数据库
![](https://i-blog.csdnimg.cn/blog_migrate/01ee3c94ff08b37858aecd670492764e.png)
连接数据库的方法很简单,直接调用几个函数就行
如果是自带的qsqlite
db = QSqlDatabase::addDatabase("QSQLITE"); //添加sqlite驱动
db.setDatabaseName("you.db"); //命名数据库
db.open(); //打开数据库
然后就可以对这个数据库进行操作啦
如果是mysql
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("127.0.0.1"); //IP,如果是本地连接 可以直接填写localhost或127.0.0.1
db.setUserName("用户名"); //用户名
db.setDatabaseName("user"); //数据库名
db.setPassword("密码"); //密码
db.setPort(3306); //端口,mysql默认为3306
if(!db.open()){
qDebug() << "失败原因:" << db.lastError().text();
}else{
qDebug() << "连接成功!!!";
}
代码部分
#include "music.h"
#include "ui_music.h"
#include <QDebug>
#include <QPropertyAnimation>
#include <QFileDialog>
#include <QMessageBox>
#include <QFileInfo>
#include <QTimer>
#include <QPainter>
Music::Music(QWidget *parent) :
QWidget(parent),
ui(new Ui::Music)
{
ui->setupUi(this);
setWindowFlag(Qt::FramelessWindowHint);
//设置图标
setWindowIcon(QIcon(":/Image/yinyue1.png"));
//创建媒体播放对象
player = new QMediaPlayer(this);
playlist = new QMediaPlaylist;
cur_index = 0;
//创建数据库
QStringList ls = QSqlDatabase::drivers();
qDebug() << ls;
db = QSqlDatabase::addDatabase("QSQLITE"); //添加sqlite驱动
db.setDatabaseName("you.db");
db.open();
QString mlist = "create table mlist(filename text,path text);";
db.exec(mlist);
QString sql = "select * from mlist;";
QSqlQuery query;
if(query.exec(sql)){
qDebug()<<"显示列表";
}else{
qDebug()<<"显示失败";
}
while(query.next() ){
QString file_name = QString(query.value("filename").toString() ); //转换类型
QString path = QString( query.value("path").toString() ); //转换类型
ui->musicList->addItem(file_name);
playlist->addMedia(QUrl::fromLocalFile(path));
totalFilelist.append(path);
cur_music = totalFilelist.at(cur_index);
count = ui->musicList->count();
qDebug()<<"count="<<count;
}
ui->songName->setVisible(false);
ui->voice_updown->setVisible(false);
//默认选中第一个音乐
ui->musicList->setCurrentRow(0);
playlist->setPlaybackMode(QMediaPlaylist::Loop);//设置循环模式
player->setPlaylist(playlist);//获取将播放列表要播放的文件
ui->voice_updown->setRange(0, 100);
ui->voice_updown->setValue(50);
//获取当前媒体的总时长
connect(player, &QMediaPlayer::durationChanged, this, &Music::updateDuration);
//获取当前播放时长
connect(player, &QMediaPlayer::positionChanged, this, &Music::updatePosition);
//拖拉进度条
connect(ui->horizontalSlider, &QSlider::valueChanged, this, &Music::setPosition);
//监听按钮
connect(ui->file, &QPushButton::clicked, this, &Music::openFile);
connect(ui->shangyishou, &QPushButton::clicked, this, &Music::shangyishou);
connect(ui->start_pause, &QPushButton::clicked, this, &Music::start_pause);
connect(ui->xiayishou, &QPushButton::clicked, this, &Music::xiayishou);
connect(ui->bofangshunxu, &QPushButton::clicked, this, &Music::bofangshunxu);
connect(ui->yinliang, &QPushButton::clicked, this, &Music::yinliang);
connect(ui->back, &QPushButton::clicked, this, &Music::back);
connect(ui->min, &QPushButton::clicked, this, &Music::min);
connect(ui->shanchu, &QPushButton::clicked, this, &Music::shanchu);
}
Music::~Music()
{
delete ui;
}
void Music::paintEvent(QPaintEvent *)
{
//加载背景
QPainter painter(this);
QPixmap pix;
pix.load(":/Image/background3.jpg");
painter.setOpacity(1);//透明度设置
painter.drawPixmap(0,0,this->width(),this->height(),pix);
}
void Music::openFile()
{
ui->voice_updown->setVisible(false);
zoom1(ui->file);
zoom2(ui->file);
QString curPash =QDir::currentPath();
QString dlgTitle="选择音频文件";
QString filter="mp3文件(*.mp3);;wav文件(*.wav);;wma文件(*.wma)";
fileList = QFileDialog::getOpenFileNames(this,dlgTitle,curPash,filter);
qDebug()<<fileList;
if(fileList.count()<1)
return;
for(int i = 0;i<fileList.count();i++)
{
//将选择的文件显示在文本框上
musicPath = fileList.at(i);
musicName = musicPath.mid(musicPath.lastIndexOf("/")+1,musicPath.lastIndexOf(".")-1-musicPath.lastIndexOf("/"));
QString sql = QString("insert into mlist values('%1','%2');").arg(musicName).arg(musicPath);
qDebug()<<"sql = " << sql;
QSqlQuery query;
if(query.exec(sql)){
qDebug()<<"插入数据库成功";
}else{
qDebug()<<"插入数据库失败";
}
ui->musicList->addItem(musicName);
playlist->addMedia(QUrl::fromLocalFile(musicPath));
}
totalFilelist.append(fileList);
cur_music = totalFilelist.at(cur_index);
}
void Music::shangyishou()
{
ui->voice_updown->setVisible(false);
zoom1(ui->shangyishou);
zoom2(ui->shangyishou);
cur_index --;
if(cur_index == -1){
cur_index = totalFilelist.count() - 1;
}
cur_music = totalFilelist.at(cur_index);
player->setMedia(QUrl::fromLocalFile(cur_music));
ui->songName->setText(cur_music.mid(cur_music.lastIndexOf("/")+1,cur_music.lastIndexOf(".")-1-cur_music.lastIndexOf("/")));
ui->songName->setVisible(true);
player->play();
ui->musicList->setCurrentRow(cur_index);
if(status1 == 1){
status1 = 2;
pix.load(":/Image/zanting.png");
ui->start_pause->setFixedSize(40, 40);
ui->start_pause->setStyleSheet("QPushButton{border:0px;}");
ui->start_pause->setIcon(pix);
ui->start_pause->setIconSize(QSize(40,40));
}
}
void Music::start_pause()
{
ui->voice_updown->setVisible(false);
if(status1 == 1){
if(pause_flag == 1){
player->play();
pause_flag = 0;
}else{
player->setMedia(QUrl::fromLocalFile(cur_music));
ui->songName->setText(cur_music.mid(cur_music.lastIndexOf("/")+1,cur_music.lastIndexOf(".")-1-cur_music.lastIndexOf("/")));
ui->songName->setVisible(true);
player->play();
}
pix.load(":/Image/zanting.png");
status1 = 2;
}else if(status1 == 2){
pix.load(":/Image/start.png");
status1 = 1;
player->pause();
pause_flag = 1;
}
ui->start_pause->setFixedSize(40, 40);
ui->start_pause->setStyleSheet("QPushButton{border:0px;}");
ui->start_pause->setIcon(pix);
ui->start_pause->setIconSize(QSize(40,40));
zoom1(ui->start_pause);
zoom2(ui->start_pause);
}
void Music::xiayishou()
{
ui->voice_updown->setVisible(false);
zoom1(ui->xiayishou);
zoom2(ui->xiayishou);
cur_index = (cur_index + 1) % totalFilelist.count();
cur_music = totalFilelist.at(cur_index);
player->setMedia(QUrl::fromLocalFile(cur_music));
ui->songName->setText(cur_music.mid(cur_music.lastIndexOf("/")+1,cur_music.lastIndexOf(".")-1-cur_music.lastIndexOf("/")));
ui->songName->setVisible(true);
player->play();
ui->musicList->setCurrentRow(cur_index);
if(status1 == 1){
status1 = 2;
pix.load(":/Image/zanting.png");
ui->start_pause->setFixedSize(40, 40);
ui->start_pause->setStyleSheet("QPushButton{border:0px;}");
ui->start_pause->setIcon(pix);
ui->start_pause->setIconSize(QSize(40,40));
}
}
void Music::bofangshunxu()
{
ui->voice_updown->setVisible(false);
if(status2 == 1){
pix.load(":/Image/xunhuan.png");
status2 ++;
}else if(status2 == 2){
pix.load(":/Image/danqu.png");
status2 ++;
}else if(status2 == 3){
pix.load(":/Image/liebiao.png");
status2 ++;
}
if(status2 > 3){
status2 = 1;
}
ui->bofangshunxu->setFixedSize(40, 40);
ui->bofangshunxu->setStyleSheet("QPushButton{border:0px;}");
ui->bofangshunxu->setIcon(pix);
ui->bofangshunxu->setIconSize(QSize(40,40));
qDebug()<<musicPath.length();
zoom1(ui->bofangshunxu);
zoom2(ui->bofangshunxu);
}
void Music::yinliang()
{
if(ui->voice_updown->isVisible()){
ui->voice_updown->setVisible(false);
}else{
ui->voice_updown->setVisible(true);
}
zoom1(ui->yinliang);
zoom2(ui->yinliang);
}
void Music::back()
{
ui->voice_updown->setVisible(false);
player->stop();
zoom1(ui->back);
zoom2(ui->back);
//告诉主场景 我返回了,主场景监听Music界面返回按钮
//延时返回
QTimer::singleShot(200,this,[=](){
emit this->MusicBack();
this->close();
player->deleteLater();
playlist->deleteLater();
this->deleteLater();
});
}
void Music::min()
{
zoom1(ui->min);
zoom2(ui->min);
//延时进入到场景中
QTimer::singleShot(200,this,[=](){ // 过0.5s后执行函数 进入场景
this->setWindowState(Qt::WindowMinimized);
});
}
void Music::shanchu()
{
ui->voice_updown->setVisible(false);
int currow = ui->musicList->currentRow();
QString path = totalFilelist.at(currow);
totalFilelist.removeOne(path);
QListWidgetItem* item = ui->musicList->currentItem(); //获取当前item
QString name_file = item->text();
QSqlQuery query;
QString sql = QString("delete from mlist where filename='%1';").arg(name_file);
if(query.exec(sql)){
qDebug()<<"删除成功";
}
else {
qDebug()<<"删除失败";
}
delete item;
playlist->removeMedia(currow);
}
void Music::updateDuration(qint64 duration)
{
music_duration = duration;
ui->tot_time->setText(QString("%1:%2").arg(duration/1000/60,2,10,QChar('0')).arg(duration/1000%60));
ui->horizontalSlider->setRange(0, duration);
ui->horizontalSlider->setEnabled(duration > 0);
ui->horizontalSlider->setPageStep(duration / 10);
}
void Music::updatePosition(qint64 position)
{
if(music_duration == position && music_duration != 0)
{
change_by_mode();
}
ui->horizontalSlider->setValue(position);
QTime duration(0, position / 60000, qRound((position % 60000) / 1000.0));
ui->cur_time->setText(duration.toString(tr("mm:ss")));
}
void Music::setPosition(int position)
{
if (qAbs(player->position() - position) > 99)
player->setPosition(position);
}
void Music::change_by_mode()
{
switch(status2){
case 1: //顺序播放
{
cur_index = (cur_index + 1) % totalFilelist.count();
ui->musicList->setCurrentRow(cur_index);
cur_music = totalFilelist.at(cur_index);
player->setMedia(QUrl::fromLocalFile(cur_music));
ui->songName->setText(cur_music.mid(cur_music.lastIndexOf("/")+1,cur_music.lastIndexOf(".")-1-cur_music.lastIndexOf("/")));
ui->songName->setVisible(true);
player->play();
break;
}
case 2: //随机播放
{
cur_index = qrand() % totalFilelist.count();
ui->musicList->setCurrentRow(cur_index);
cur_music = totalFilelist.at(cur_index);
player->setMedia(QUrl::fromLocalFile(cur_music));
ui->songName->setText(cur_music.mid(cur_music.lastIndexOf("/")+1,cur_music.lastIndexOf(".")-1-cur_music.lastIndexOf("/")));
ui->songName->setVisible(true);
player->play();
break;
}
case 3: //单曲循环
{
cur_music = totalFilelist.at(cur_index);
player->setMedia(QUrl::fromLocalFile(cur_music));
ui->songName->setText(cur_music.mid(cur_music.lastIndexOf("/")+1,cur_music.lastIndexOf(".")-1-cur_music.lastIndexOf("/")));
ui->songName->setVisible(true);
player->play();
break;
}
default:
break;
}
}
void Music::on_musicList_doubleClicked(const QModelIndex &index)
{
ui->voice_updown->setVisible(false);
cur_index = index.row();
cur_music = totalFilelist.at(cur_index);
player->setMedia(QUrl::fromLocalFile(cur_music));
ui->musicList->setCurrentRow(cur_index);
ui->songName->setText(cur_music.mid(cur_music.lastIndexOf("/")+1,cur_music.lastIndexOf(".")-1-cur_music.lastIndexOf("/")));
ui->songName->setVisible(true);
player->play();
if(status1 == 1){
status1 = 2;
pix.load(":/Image/zanting.png");
ui->start_pause->setFixedSize(40, 40);
ui->start_pause->setStyleSheet("QPushButton{border:0px;}");
ui->start_pause->setIcon(pix);
ui->start_pause->setIconSize(QSize(40,40));
}
}
void Music::on_voice_updown_valueChanged(int value)
{
player->setVolume(value);
}
若有不懂之处,欢迎评论区留言或私信,制作不易,请点个赞和收藏吧!