大一下學期c++課程設計,作了個仿酷狗的音樂播放器。c++
總體作的比較粗略,如今大三看還遠遠不足。app
Win8+QT5.21+Qt creator 3.01less
:表 1 播放器控件的主要組成部分dom
組成控件ide |
功能函數 |
播放/暫停按鈕oop |
播放當前音樂文件或者暫停播放測試 |
上一首按鈕ui |
播放列表中當前MP3文件的上一首MP3文件this |
下一首按紐 |
播放列表中當前MP3文件的下一首MP3文件 |
打開按鈕 |
選擇一首MP3文件 |
列表按鈕 |
顯示隱藏播放列表窗口 |
歌詞按鈕 |
顯示隱藏歌詞顯示窗口 |
靜音按鈕 |
打開/關閉播放器的輸出聲音 |
音量控制條 |
對播放器的音量大小進行調節 |
進度控制條 |
對當前播放的MP3文件的播放進度進行調節 |
歌名顯示 |
對當前播放的MP3歌名顯示 |
歌曲時間顯示 |
對當前播放的MP3文件的播放時間與總時長顯示 |
播放模式 |
對歌曲的播放模式進行選擇 |
最小化,關閉 |
把窗口最小化,關閉窗口 |
1) 歌詞功能未能實現
2) 定位功能未能實現
3) 進度與音量必須拖動slider,不然無響應
4) 歌名過長時,歌曲播放列比例不一致
5) 當鼠標通過功能按鈕時,圖標無變化
6) 關閉窗口出現中文沒法支持錯誤,沒法解決,改用英文。
main.cpp
#include "dialog.h" #include <QtWidgets/QApplication> #include <QDesktopWidget> #if _MSC_VER >= 1600 #pragma execution_character_set("utf-8") #endif int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.setWindowFlags(Qt::FramelessWindowHint);//去掉窗口標題欄 w.show(); //將窗口放置在屏幕靠左,獲取屏幕的高-窗體的高除以2. w.move(((QApplication::desktop()->width()-w.width())*0.25), (QApplication::desktop()->height()-w.height())>>1); return a.exec(); }
dialog.cpp
#include "dialog.h" #include "ui_dialog.h" #include "QMediaPlayer" #include "QFile" //一個操做文件的輸入/輸出設備 #include "QDir" #include "QFileDialog" #include "QMediaPlaylist" #include "QTime" #include <QMessageBox> #include <QDebug> //測試用 Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog)//,lrcUi(new Ui::lrcDialog) { playList=new QMediaPlaylist; player =new QMediaPlayer; ui->setupUi(this); ui->progressBar->setRange(0,0);//初始化進度條,範圍0到0,進度條沒法拖動 ui->songList->setColumnWidth(0,200);//初始化歌曲列表的列寬 ui->songList->setRowHeight(0,60);//初始化歌曲列表的行寬 ui->findFrame->hide();//查找窗口默認隱藏 /* * 播放模式選擇的菜單 */ currentItemInLoop = new QAction(tr("單曲循環"), this); sequential = new QAction(tr("順序播放"), this); loop = new QAction(tr("列表循環"), this); random = new QAction(tr("隨機播放"), this); model = new QMenu(tr("播放模式"),this); model->addAction(currentItemInLoop); model->addAction(sequential); model->addAction(loop); model->addAction(random); playSong= new QAction(tr("播放"), this); connect(playSong, SIGNAL(triggered()), this, SLOT(on_play_clicked())); stopSong= new QAction(tr("暫停"), this); connect(stopSong, SIGNAL(triggered()), this, SLOT(on_play_clicked())); nextSong= new QAction(tr("下一音樂"), this); connect(nextSong, SIGNAL(triggered()), this, SLOT(on_nextSong_clicked())); previousSong= new QAction(tr("上一音樂"), this); connect(previousSong, SIGNAL(triggered()), this, SLOT(on_firstSong_clicked())); /* * 托盤圖標的右鍵菜單 */ trayIcon = new QSystemTrayIcon(this); trayMenu = new QMenu(this); trayIcon->setIcon(QIcon(":/images/tray.png")); minimizeAction = new QAction(tr("最小化"), this); connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide())); quitAction = new QAction(tr("關閉程序"), this); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); trayMenu->addAction(playSong); trayMenu->addAction(stopSong); trayMenu->addAction(nextSong); trayMenu->addAction(previousSong); trayMenu->addSeparator(); trayMenu->addMenu(model); trayMenu->addSeparator(); trayMenu->addAction(minimizeAction); trayMenu->addAction(quitAction); trayIcon->show(); trayIcon->setContextMenu(trayMenu); //托盤圖標添加單/雙擊鼠標相應 connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this,SLOT(trayiconActivated(QSystemTrayIcon::ActivationReason))); /* * 歌曲列表的右鍵菜單 */ songMenu= new QMenu(this); addSong= new QAction(tr("添加歌曲"), this); connect(addSong, SIGNAL(triggered()), this, SLOT(on_open_clicked())); delSong= new QAction(tr("刪除歌曲"), this); connect(delSong, SIGNAL(triggered()), this, SLOT(delMusic())); clearList= new QAction(tr("清空播放列表"), this); connect(clearList, SIGNAL(triggered()), this, SLOT(clearMusic())); songMenu->addAction(playSong); songMenu->addAction(addSong); songMenu->addAction(delSong); songMenu->addAction(clearList); ui->songList->setContextMenuPolicy(Qt::CustomContextMenu); //add="D:/QTWLXI/Music1/MUSIC/sor/咱們的歌.mp3";// test //player->setMedia(QUrl::fromLocalFile(add));// test player->setPlaylist(playList);//設置相應playlist player->setVolume(100);//設置初始化音量 isSilence=false;//默認不靜音 isPlay=false;//默認不播放歌曲 isOpenLyric=true;//默認打開歌詞 //進度條改變時播放位置隨着改變 connect(ui->progressBar,SIGNAL(sliderMoved(int)),this,SLOT(setPlayerPosition(int))); //當播放歌曲位置改變時 progressBar設置對應的位置 對應的播放時間與總時間的顯示 connect(player,SIGNAL(positionChanged(qint64)),this,SLOT(positionChanged(qint64))); // 當progressBar改變時 構造歌曲總時間 connect(player, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged(qint64))); //songList 雙擊播放選中的 connect(ui->songList,SIGNAL(cellDoubleClicked(int,int)),this,SLOT(playto(int,int))); //顯示歌名 connect(playList,SIGNAL(currentIndexChanged(int)),this,SLOT(showSongName(int))); // connect(playList,SIGNAL(currentIndexChanged(int)),this,SLOT(showLyric(int))); //播放模式設置 /* 信號無參數的狀況下,沒法直接給槽傳入參數,次方法違背信號與槽參數一致,解決方法在下面 * connect(currentItemInLoop, SIGNAL(triggered()), this, SLOT(setPlayModel(0))); connect(sequential, SIGNAL(triggered()), this, SLOT( setPlayModel(1))); connect(loop, SIGNAL(triggered()), this, SLOT( setPlayModel(2))); connect(random, SIGNAL(triggered()), this, SLOT( setPlayModel(3))); */ //讓action響應相應的model槽,讓model槽設置相應信號selectedModel的參數在傳給setPlayModel connect(this, SIGNAL(selectedModel(int)), this, SLOT( setPlayModel(int))); connect(this, SIGNAL(selectedModel(int)), this, SLOT( setPlayModel(int))); connect(this, SIGNAL(selectedModel(int)), this, SLOT( setPlayModel(int))); connect(this, SIGNAL(selectedModel(int)), this, SLOT( setPlayModel(int))); connect(currentItemInLoop, SIGNAL(triggered()), this, SLOT( model0())); connect(sequential, SIGNAL(triggered()), this, SLOT( model1())); connect(loop, SIGNAL(triggered()), this, SLOT( model2())); connect(random, SIGNAL(triggered()), this, SLOT( model3())); } void Dialog::model0() { emit selectedModel(0); } void Dialog::model1() { emit selectedModel(1); } void Dialog::model2() { emit selectedModel(2); } void Dialog::model3() { emit selectedModel(3); } Dialog::~Dialog() { delete ui; } /* * 刪除歌曲 */ void Dialog::delMusic(){ static int b=0; if (QMessageBox::Yes == QMessageBox::question(this, tr("Question"), tr("Sure you want to delete this song?"), QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes)) { int i=ui->songList->currentRow(); playList->clear(); ui->songList->clear(); songName.removeAt(i); qDebug()<<i<<endl; QString s = QString::number(i, 10); for(int j=0;j<songName.length();j++) ui->songList->setItem(++b, 0, new QTableWidgetItem(s+" "+songName[i])); ui->strTime->setText("00:00"); QMessageBox::information(this, tr("information"), tr("刪除成功")); } else { QMessageBox::information(this,tr("information"),tr("取消刪除")); } } /* * 清空列表 */ void Dialog::clearMusic(){ playList->clear(); ui->songList->clear(); ui->songList->setRowCount(0); ui->strTime->setText("00:00"); } /* * 音量調節 */ void Dialog::on_volume_sliderMoved(int position) { player->setVolume(position); ui->volume->setValue(position); if(position==0){ ui->silence->setIcon(QIcon(":/images/silence.png")); isSilence=true; }else{ ui->silence->setIcon(QIcon(":/images/nosilence.png")); isSilence=false; } } /* * 靜音及恢復 */ void Dialog::on_silence_clicked() { isSilence=!isSilence; if(isSilence) { volumeValue=ui->volume->value(); on_volume_sliderMoved(0); //記錄靜音前的音量 ui->silence->setIcon(QIcon(":/images/silence.png")); } else { on_volume_sliderMoved(volumeValue);//恢復靜音前的音量 ui->silence->setIcon(QIcon(":/images/nosilence.png")); } } /* * 添加歌曲 */ void Dialog::on_open_clicked() { QString initialName=QDir::homePath();//在window下返回用戶(即個人文檔)目錄 //getOpenFileNames(指定父組件,對話框的標題,默認打開的目錄,後綴名過濾器,若是須要使用多個過濾器 使用";;"分割 // ,是默認選擇的過濾器,對話框的一些參數設定,好比只顯示文件夾等等,) QStringList pathList=QFileDialog::getOpenFileNames(this, tr("選擇文件"), initialName, tr("MP3 Files (*.mp3)")); //用一個QStringList列表 存放音樂文件的地址,可多選音樂。 for(int i=0; i<pathList.size(); ++i) { QString path=QDir::toNativeSeparators(pathList.at(i));//把斜槓轉化成反斜槓,獲取歌曲的地址 if(!path.isEmpty()) { playList->addMedia(QUrl::fromLocalFile(path)); //QUrl::fromLocalFile()必定要用這個方法,由於若是文件名或路徑有中文或空格,就打不開文件. //直接用QUrl(fileName)只能打開英文名稱和沒有空格路徑的文件. QString fileName=path.split("\\").last();//用split 獲取文件名(包含後綴) 例 music.mp3 int rownum=ui->songList->rowCount();//行數 ui->songList->insertRow(rownum);//插入空行 QString s = QString::number(ui->songList->rowCount(), 10); QString Name=fileName.split(".").front(); ui->songList->setItem(rownum, 0, new QTableWidgetItem(s+" . "+Name)); songName.append(Name); } } } /* * 下一曲 */ void Dialog::on_nextSong_clicked() { //若是播放列表爲空,按鈕不可用,直接返回 if(playList->isEmpty()) return; //若是列表到盡頭,則回到列表開頭 int currentIndex=playList->currentIndex(); if(++currentIndex==playList->mediaCount()) currentIndex=0; //設置當前的currentIndex playList->setCurrentIndex(currentIndex); isPlay=true; on_play_clicked(); } /* * 上一曲 */ void Dialog::on_firstSong_clicked() { //播放列表爲空,按鈕不可用,直接返回 if(playList->isEmpty()) return; //若是列表到開頭,則中止播放,直接返回 int currentIndex=playList->currentIndex(); if(currentIndex==0){ isPlay=false; on_play_clicked(); return; } playList->previous(); isPlay=true; on_play_clicked(); } /* * 播放和暫停 */ void Dialog::on_play_clicked() { //若是播放列表爲空,按鈕不可用,直接返回 if(playList->isEmpty()) return; isPlay=!isPlay; if(isPlay) { player->pause(); ui->play->setIcon(QIcon(":/images/play.png"));// 暫停時候顯示播放圖標 ui->play->setToolTip(tr("暫停")); } else { player->play(); ui->play->setIcon(QIcon(":/images/pause.png"));// 播放時候顯示暫停圖標 ui->play->setToolTip(tr("播放")); } } /* * 當進度條改變時,設置歌曲對應的播放位置 */ void Dialog::setPlayerPosition(int position) { player->setPosition(position); } /* * 當播放歌曲位置改變時 progressBar設置對應的位置 對應的播放時間與總時間的顯示 */ void Dialog::positionChanged(qint64 position)// { ui->progressBar->setValue(position);//position 單位:毫秒 1000ms=1s currentTime=new QTime(0,(position/60000)%60,(position/1000)%60);//構造當前時間(小時,分鐘,秒和毫秒)。 ui->strTime->setText(currentTime->toString("mm:ss"));//播放時間 輸出時間格式09:02(都是兩位) } /* * 當progressBar改變時 構造歌曲總時間 */ void Dialog::durationChanged(qint64 duration)// { ui->progressBar->setRange(0,duration);//progressBar的範圍從0到duration(總時間) totalTime=new QTime(0,(duration/60000)%60,(duration/1000)%60); ui->endTime->setText(totalTime->toString("mm:ss"));//歌曲總時間 } /* * 當雙擊songList時 播放雙擊的歌曲 */ void Dialog::playto(int i,int ) { playList->setCurrentIndex(i); isPlay=true; on_play_clicked(); } /* * 當前播放歌曲名顯示 */ void Dialog::showSongName(int i) { ui->songList->selectRow(i); //播放到這首歌曲的時候選中 QString playtitle=songName[i]; ui->showSongName->setText(playtitle); } /* * 設置播放方式 QMediaPlaylist::PlaybackMode */ void Dialog::setPlayModel(int i) { switch (i) { case 0: playList->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);//單曲循環 ui->playModel->setIcon(QIcon(":/images/CurrentItemInLoop.png")); ui->playModel->setToolTip(tr("單曲循環")); break; case 1: playList->setPlaybackMode(QMediaPlaylist::Sequential);//順序播放 ui->playModel->setIcon(QIcon(":/images/Sequential.png")); ui->playModel->setToolTip(tr("順序播放")); break; case 2: playList->setPlaybackMode(QMediaPlaylist::Loop);//列表循環 ui->playModel->setIcon(QIcon(":/images/Loop.png")); ui->playModel->setToolTip(tr("列表循環")); break; case 3: playList->setPlaybackMode(QMediaPlaylist::Random);//隨機播放 ui->playModel->setIcon(QIcon(":/images/Random.png")); ui->playModel->setToolTip(tr("隨機播放")); break; } } /* * 模擬標題欄移動消息,使之能夠移動 */ void Dialog::mousePressEvent(QMouseEvent *event) { if (ReleaseCapture()) SendMessage(HWND(this->winId()), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0); event->ignore(); } /* * 窗口最小化 */ void Dialog::on_minWindow_clicked() { //系統自定義的最小化窗口函數 showMinimized(); //最大化 showMaximized(); } /* * 窗口關閉 */ void Dialog::on_closeWindow_clicked() { //系統自定義的窗口關閉函數 close(); } /* * 處理關閉事件 */ void Dialog::closeEvent(QCloseEvent *event) { QMessageBox::StandardButton button; button = QMessageBox::question(this,tr("Exit the program"), tr("Do you really want to exit the program"), QMessageBox::Yes|QMessageBox::No); if (button == QMessageBox::No) { event->ignore(); //忽略退出信號,程序繼續運行 } else if (button == QMessageBox::Yes) { event->accept(); //接受退出信號,程序退出 } } /* * 播放模式的菜單 */ void Dialog::on_playModel_clicked() { QPoint pos(this->x()+47,this->y()+91);//播放模式菜單起點座標 model->exec(pos);//讓播放模式菜單在固定的點顯示 } void Dialog::trayiconActivated(QSystemTrayIcon::ActivationReason reason) { if(reason==QSystemTrayIcon::Trigger||QSystemTrayIcon::DoubleClick){ this->showNormal(); this->raise(); } } /* * 歌曲列表右鍵菜單 */ void Dialog::on_songList_customContextMenuRequested(const QPoint &pos) { songMenu->exec(QCursor::pos()); } /* * 顯示查找窗口 */ void Dialog::on_find_clicked() { ui->findFrame->show(); } /* * 關閉查找窗口 */ void Dialog::on_close_clicked() { ui->findFrame->hide(); } /* * 查找功能 */ void Dialog::on_enter_clicked() { QString song=ui->lineEdit->text(); static int a=0; for(int i=0;i<songName.length();i++){ if(songName[i].contains(song)){ ui->songList->clear(); ui->songList->setItem(a++, 0, new QTableWidgetItem(songName[i])); } } } /* 方法做廢 只能顯示LRC的所有內容,沒法隨時時間只顯示歌詞 void Dialog::showLyric(int z){ //顯示歌詞部分 if(isOpenLyric==true) { QString str=songName[z]; qDebug()<<songName[z]<<endl; QFile file("C:\\Users\\k\\Desktop\\musicplayer\\Music3.0\\"+str+".lrc");// qDebug()<<"C:\\Users\\k\\Desktop\\musicplayer\\Music3.0\\"+str+".lrc"<<endl; if(!file.open(QIODevice::ReadOnly|QIODevice::Text)) { QMessageBox::information(this, tr("information"), tr("當前目錄下未找到歌詞文件")); } else { QTextStream in(&file); QString result=in.readAll(); ui->textEdit->setText(result); } } } void Dialog::on_lyric_clicked() { isOpenLyric=!isOpenLyric; if(isOpenLyric==true){ ui->textEdit->hide(); }else{ ui->textEdit->show(); } } */ void Dialog::on_position_clicked() { //TODO 沒法使用,沒法使當前播放的歌曲被定位 int i=ui->songList->currentRow(); ui->songList->visualRow(i); }
dialog.h
#ifndef DIALOG_H #define DIALOG_H #include "QDialog" #include "QtMultimedia" #include <QCloseEvent> #include <QMenu> #include <QSystemTrayIcon> class QMediaPlaylist; class QMediaPlayer; namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); signals: void selectedModel(int); private slots: void on_volume_sliderMoved(int position); void on_silence_clicked(); void on_open_clicked(); void on_nextSong_clicked(); void on_firstSong_clicked(); void on_play_clicked(); void setPlayerPosition(int); void positionChanged(qint64 position); void durationChanged(qint64 duration); void playto(int,int); void showSongName(int ); void setPlayModel(int); void on_closeWindow_clicked();//關閉窗口 void on_minWindow_clicked();//最小化窗口 void on_playModel_clicked(); void delMusic(); void clearMusic(); void model0(); void model1(); void model2(); void model3(); void trayiconActivated(QSystemTrayIcon::ActivationReason reason); void on_songList_customContextMenuRequested(const QPoint &pos); void on_find_clicked(); void on_close_clicked(); void on_enter_clicked(); //void on_lyric_clicked(); // void showLyric(int); void on_position_clicked(); private: Ui::Dialog *ui; QStringList songName; QMediaPlayer *player; QMediaPlaylist *playList; bool isSilence; bool isPlay; bool isOpenLyric; QTime *currentTime; QTime *totalTime; QAction *currentItemInLoop; QAction *sequential; QAction *loop; QAction *random; QMenu *trayMenu; QMenu *model; QSystemTrayIcon *trayIcon; QAction *playSong; QAction *stopSong; QAction *nextSong; QAction *previousSong; QAction *quitAction; QAction *minimizeAction; QMenu *songMenu; QAction *addSong; QAction *delSong; QAction *clearList; int volumeValue; void Dialog::mousePressEvent(QMouseEvent *event); void closeEvent(QCloseEvent *event); }; #endif // DIALOG_H