Qt自制多功能程序设计——Qt音乐播放器(结合数据库mysql、qsqlite)

该文详细介绍了如何使用Qt框架构建一个音乐播放器,包括利用QMediaPlayer进行音乐播放,使用QSqlDatabase管理歌曲列表,通过QSlider定制进度条样式,以及实现各种播放模式和控制功能。
摘要由CSDN通过智能技术生成

本篇开始讲上次说的Qt自制多功能程序功能之一的音乐播放器

实现功能

  1. 利用数据库,打开音乐播放器自动读取已添加的歌曲,并可以随时添加或删除歌曲;

  1. 提供上一首、下一首、暂停/播放、播放方式(单曲循环/随机播放/顺序播放)、音量调节、添加歌曲、删除歌曲按键;

  1. 显示当前正在播放的歌曲,并时刻更新进度条以及播放时间;

  1. 双击播放列表亦可播放歌曲;

  1. 利用qt样式表进行美化。

界面设计(ui)

进度条用的也是Qt自带的QSlider,但是原始的QSlider不够美观,这里进行了样式表编辑,如图所示打开样式表

在样式表里添加如下内容,此处将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;

会出现如下信息,说明你可以连接至对应的数据库

连接数据库的方法很简单,直接调用几个函数就行

如果是自带的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);
}

若有不懂之处,欢迎评论区留言或私信,制作不易,请点个赞和收藏吧!

  • 11
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值