Qt学习笔记-编写简易的音乐播放器

程序运行截图如下:
这里写图片描述

再次添加一个音乐并播放:
这里写图片描述

代码如下:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QModelIndex>

class QThread;
class QTreeWidgetItem;
class QMediaPlayer;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    void saveData();    //每次正常关闭时,就自动保存
    void readData();    //每次打开程序时,就自动读取
    void closeEvent(QCloseEvent *event);
    ~Widget();

private slots:
    void onListContextMenu(const QPoint &pt);
    void onMenuAdd();
    void onMenuRemove();
    void updateTreeWidget(bool available);

    void listDoubleClicked(QTreeWidgetItem *item, int col);
    void refreshPlayStatus(QModelIndex index);


private:
    Ui::Widget *ui;
    QString m_newMusic;
    QMediaPlayer *m_metaInformationResolver;
    QMediaPlayer *m_player;

};

#endif // WIDGET_H

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QTextStream>
#include <QFile>
#include <windows.h>
#include <QThread>
#include <QMenu>
#include <QFileDialog>
#include <QTreeWidgetItem>
#include <QMediaPlayer>
#include <QCloseEvent>
#include <QUrl>
#include <QTime>
#include <QMediaContent>


Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    QStringList headList;
    headList<<"歌曲名"<<"作者"<<"歌曲长度"<<"文件路径"<<"是否播放";
    ui->treeWidget->setHeaderLabels(headList);
    ui->treeWidget->setColumnWidth(3,250);
    ui->treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);
    connect(ui->actionAdd,&QAction::triggered,this,&Widget::onMenuAdd);
    connect(ui->actionRemove,&QAction::triggered,this,&Widget::onMenuRemove);
    connect(ui->treeWidget,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(onListContextMenu(QPoint)));

    connect(ui->addPushButton,SIGNAL(clicked(bool)),this,SLOT(onMenuAdd()));

    m_metaInformationResolver=new QMediaPlayer(this);
    connect(m_metaInformationResolver,&QMediaPlayer::metaDataAvailableChanged,this,&Widget::updateTreeWidget);
    readData();

    m_player=new QMediaPlayer;
    connect(ui->treeWidget,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this,SLOT(listDoubleClicked(QTreeWidgetItem*,int)));
    connect(ui->treeWidget,SIGNAL(doubleClicked(QModelIndex)),this,SLOT(refreshPlayStatus(QModelIndex)));
}


void Widget::saveData()
{
    QFile file("musicPath.data");
    if(file.open(QIODevice::WriteOnly|QIODevice::Text)){
        QTextStream stream(&file);
        QTreeWidgetItemIterator it(ui->treeWidget);
        while(*it){
            stream<<(*it)->text(3)<<"\n";
            it++;
        }
        file.close();
    }

}

void Widget::readData()
{
    QFile file("musicPath.data");
    if(!file.open(QIODevice::ReadOnly|QIODevice::Text)){
        return;
    }
    while(!file.atEnd()){
       m_newMusic=file.readLine();
       m_newMusic=m_newMusic.left(m_newMusic.size()-1);

       //估计的问题是 读取太快了,估计要放入一个线程里面,然后每秒调用一次来试试
       m_metaInformationResolver->setMedia(QUrl::fromLocalFile(m_newMusic));
    }
    file.close();

}

void Widget::closeEvent(QCloseEvent *event)
{

    saveData();
    qApp->exit();
}

void Widget::refreshPlayStatus(QModelIndex index)
{
    QTreeWidgetItemIterator it(ui->treeWidget);
    qDebug()<<index.row();
    int rowIndex=0;
    while(*it){
        if(rowIndex==index.row()){
            (*it)->setText(4,"播放中");
        }
        else{
            (*it)->setText(4,"否");
        }
        ++it;
        rowIndex++;
    }
}


Widget::~Widget()
{
    delete ui;
}

void Widget::onListContextMenu(const QPoint &pt)
{
    QTreeWidgetItem *selected=ui->treeWidget->itemAt(pt);

    QMenu menu;
    if(selected){
        menu.addAction(ui->actionRemove);
    }
    else{
        menu.addAction(ui->actionAdd);
    }

    menu.exec(ui->treeWidget->mapToGlobal(pt));

}

void Widget::onMenuAdd()
{
    m_newMusic=QFileDialog::getOpenFileName(this,"选择mp3文件","D:\\","mp3文件(*.mp3)");
    if(!m_newMusic.isEmpty()){
        //添加文件
        m_newMusic.replace("/","\\");
        m_metaInformationResolver->setMedia(QMediaContent(QUrl::fromLocalFile(m_newMusic)));
    }
}

void Widget::onMenuRemove()
{
    QTreeWidgetItem *item=ui->treeWidget->takeTopLevelItem(ui->treeWidget->currentIndex().row());

    if(item){
        delete item;
    }
}

void Widget::updateTreeWidget(bool available)
{
    if(!available)
        return;
    qDebug()<<"void Widget::updateTreeWidget(bool available)";
    QString title,author;
    qint64 duration;
    title=m_metaInformationResolver->metaData("Title").toString();
    if(title=="")
        title="未知";
    author=m_metaInformationResolver->metaData("Author").toString();
    if(author=="")
        author="未知";
    duration=m_metaInformationResolver->metaData("Duration").toInt()/1000;
    QTime totalTime((duration/3600)%60,(duration/60)%60, duration%60,(duration*1000)%1000);
    QString format="mm:ss";
    if(duration>3600)
        format="hh:mm:ss";

    //添加到TreeWidget里面
    QStringList list;
    list.append(title);
    list.append(author);
    list.append(totalTime.toString(format));
    list.append(m_newMusic);
    list.append("否");   //默认不播放
    QTreeWidgetItem *newItem=new QTreeWidgetItem(ui->treeWidget,list);
    ui->treeWidget->addTopLevelItem(newItem);
}

void Widget::listDoubleClicked(QTreeWidgetItem *item,int col)
{
    Q_UNUSED(col)
    m_player->setMedia(QUrl::fromLocalFile(item->text(3)));
    m_player->play();
    //m_player->playlist(XXXX);播放列表
}

main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

猜你喜欢

转载自blog.csdn.net/qq78442761/article/details/80853950