使用Qt做一個簡易音樂播放器【Phonon淺談--續】

在第一篇 Phonon淺談 中提及到了 Phonon 這個多媒體框架的一些基本知識,於是想着結合這些基本知識來實踐一番,做一個簡單的音樂播放器。

 

【步驟一】

新建一個 Qt Gui 工程,在建立過程中需要包含 Phonon 模塊,之後生成文件如下圖:

 

 

Qt Gui 工程會生成一個 ui 文件,在這裏是 mainwindow.ui 。雙擊 mainwindow.ui 進行一番簡單的佈局,如下圖:

 

關於這個 ui 界面,中央位置是一個 QListWidget ,用來顯示音樂文件列表;下面一欄紅色矩形是一個 QVBoxLayout 垂直佈局部件,用來確定等會要建立的播放進度條的位置;而下面則是四個相關控制按鈕。

大概地說, Phonon 的工作機制是使用 MediaObject 來管理 MediaSource 即源文件,通過 Path 連接到 AudioOutput ,最後是由 AudioOutput 將數據發送到相關物理設備。

於是有了步驟二。


 

【步驟二】

步驟一是用來實現基本的界面,而步驟二是用代碼實現具體的功能。

基於對 Phonon 的認識,有了以下四點:

① 使用 MediaObject 管理媒體源

② 使用 AudioOutput 連接物理設備

③ 使用 SeekSlider 實現進度條

④ 使用 QList 實現播放列表

於是產生了相應的代碼:

view plaincopy to clipboardprint?
Phonon::MediaObject *mediaObject;  
Phonon::AudioOutput *audioOutput;  
Phonon::SeekSlider *seekSlider;  
QList<Phonon::MediaSource> sourceList;//播放列表 
    Phonon::MediaObject *mediaObject;
    Phonon::AudioOutput *audioOutput;
    Phonon::SeekSlider *seekSlider;
    QList<Phonon::MediaSource> sourceList;//播放列表

並且需要在構造函數裏面將 mediaObject 和 audioOutput 連接起來:

view plaincopy to clipboardprint?
Phonon::createPath(mediaObject, audioOutput); 
    Phonon::createPath(mediaObject, audioOutput);


從而使得數據能從 mediaObject 到達 audioOutput ,再通過物理設備播放。

 

1、  要播放音樂首先需要有源文件,所以先實現添加文件的功能。

首先,將添加按鈕和添加功能連接起來:

view plaincopy to clipboardprint?
connect(this->ui->addBtn, SIGNAL(clicked()), this, SLOT(addFiles())); 
connect(this->ui->addBtn, SIGNAL(clicked()), this, SLOT(addFiles()));


              從而實現點擊按鈕激活相應操作的功能,而添加音樂文件的槽的代碼如下:

view plaincopy to clipboardprint?
void MainWindow::addFiles(){  
    QStringList files = QFileDialog::getOpenFileNames(this, tr("Selec Files to play"));  
    QString file;  
    foreach(file, files){  
        this->ui->listWidget->addItem(file);  
        sourceList.append(file);  
    }  

void MainWindow::addFiles(){
    QStringList files = QFileDialog::getOpenFileNames(this, tr("Selec Files to play"));
    QString file;
    foreach(file, files){
        this->ui->listWidget->addItem(file);
        sourceList.append(file);
    }
}

上述代碼是使用 QFileDialog 的 getOpenFileNames 方法獲取若干個音樂文件,然後再使用 Qt 中的 foreach 遍歷每個選中的文件,將其添加到播放列表中。

2、  播放、暫停和停止的基本實現

同樣的先將信號和槽連接起來:

view plaincopy to clipboardprint?
    connect(this->ui->playBtn, SIGNAL(clicked()), this, SLOT(playFile()));  
    connect(this->ui->pauseBtn, SIGNAL(clicked()), this, SLOT(pauseFile()));  
connect(this->ui->stopBtn, SIGNAL(clicked()), this, SLOT(stopFile())); 
    connect(this->ui->playBtn, SIGNAL(clicked()), this, SLOT(playFile()));
    connect(this->ui->pauseBtn, SIGNAL(clicked()), this, SLOT(pauseFile()));
connect(this->ui->stopBtn, SIGNAL(clicked()), this, SLOT(stopFile()));

              之後再具體實現相應的簡單功能,這裏列出 playFile 的代碼:

view plaincopy to clipboardprint?
void MainWindow::playFile(){  
    if(sourceList.isEmpty()){  
        QMessageBox::information(this, tr("no music files"), tr("no files to play"));  
        return ;  
    }  
    mediaObject->setQueue(sourceList);  
    mediaObject->play();  
    this->ui->playBtn->setEnabled(false);  
    this->ui->pauseBtn->setEnabled(true);  

void MainWindow::playFile(){
    if(sourceList.isEmpty()){
        QMessageBox::information(this, tr("no music files"), tr("no files to play"));
        return ;
    }
    mediaObject->setQueue(sourceList);
    mediaObject->play();
    this->ui->playBtn->setEnabled(false);
    this->ui->pauseBtn->setEnabled(true);
}

首先判斷列表是否爲空,接着設置播放隊列,然後播放當前文件,最後使得播放按鈕不可用,而激活暫停按鈕。其它的功能類似,都是使用 mediaObject 的方法。

 

【步驟三】

這裏只簡單地實現播放功能,當然還是可以再繼續擴展功能,不過這是後話了。

運行的效果圖如下:

 

此時就能聽見蠻好聽的《左邊》了^_^

 

以下是全部代碼:

mainwindow.h:

view plaincopy to clipboardprint?
#ifndef MAINWINDOW_H  
#define MAINWINDOW_H  
#include <QMainWindow>  
#include <Phonon>  
#include <QList>  
namespace Ui {  
    class MainWindow;  
}  
class MainWindow : public QMainWindow {  
    Q_OBJECT  
public:  
    MainWindow(QWidget *parent = 0);  
    ~MainWindow();  
protected:  
    void changeEvent(QEvent *e);  
private slots:  
    void addFiles();  
    void playFile();  
    void pauseFile();  
    void stopFile();  
private:  
    Ui::MainWindow *ui;  
    Phonon::MediaObject *mediaObject;  
    Phonon::AudioOutput *audioOutput;  
    Phonon::SeekSlider *seekSlider;  
    QList<Phonon::MediaSource> sourceList;//播放列表  
};  
#endif // MAINWINDOW_H 
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <Phonon>
#include <QList>
namespace Ui {
    class MainWindow;
}
class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
protected:
    void changeEvent(QEvent *e);
private slots:
    void addFiles();
    void playFile();
    void pauseFile();
    void stopFile();
private:
    Ui::MainWindow *ui;
    Phonon::MediaObject *mediaObject;
    Phonon::AudioOutput *audioOutput;
    Phonon::SeekSlider *seekSlider;
    QList<Phonon::MediaSource> sourceList;//播放列表
};
#endif // MAINWINDOW_H
 

mainwindow.cpp:

view plaincopy to clipboardprint?
#include <QtGui>  
#include "mainwindow.h"  
#include "ui_mainwindow.h"  
MainWindow::MainWindow(QWidget *parent) :  
    QMainWindow(parent),  
    ui(new Ui::MainWindow)  
{  
    ui->setupUi(this);  
    connect(this->ui->addBtn, SIGNAL(clicked()), this, SLOT(addFiles()));  
    connect(this->ui->playBtn, SIGNAL(clicked()), this, SLOT(playFile()));  
    connect(this->ui->pauseBtn, SIGNAL(clicked()), this, SLOT(pauseFile()));  
    connect(this->ui->stopBtn, SIGNAL(clicked()), this, SLOT(stopFile()));  
    mediaObject = new Phonon::MediaObject(this);  
    audioOutput = new Phonon::AudioOutput(this);  
    seekSlider = new Phonon::SeekSlider(this);  
    Phonon::createPath(mediaObject, audioOutput);  
    seekSlider->setMediaObject(mediaObject);  
    this->ui->seekLayout->addWidget(seekSlider);  
}  
MainWindow::~MainWindow()  
{  
    delete ui;  
}  
void MainWindow::changeEvent(QEvent *e)  
{  
    QMainWindow::changeEvent(e);  
    switch (e->type()) {  
    case QEvent::LanguageChange:  
        ui->retranslateUi(this);  
        break;  
    default:  
        break;  
    }  
}  
void MainWindow::addFiles(){  
    QStringList files = QFileDialog::getOpenFileNames(this, tr("Selec Files to play"));  
    QString file;  
    foreach(file, files){  
        this->ui->listWidget->addItem(file);  
        sourceList.append(file);  
    }  
}  
void MainWindow::playFile(){  
    if(sourceList.isEmpty()){  
        QMessageBox::information(this, tr("no music files"), tr("no files to play"));  
        return ;  
    }  
    mediaObject->setQueue(sourceList);  
    mediaObject->play();  
    this->ui->playBtn->setEnabled(false);  
    this->ui->pauseBtn->setEnabled(true);  
}  
void MainWindow::pauseFile(){  
    mediaObject->pause();  
    this->ui->pauseBtn->setEnabled(false);  
    this->ui->playBtn->setEnabled(true);  
}  
void MainWindow::stopFile(){  
    mediaObject->stop();  
    this->ui->pauseBtn->setEnabled(true);  
    this->ui->playBtn->setEnabled(true);  

#include <QtGui>
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(this->ui->addBtn, SIGNAL(clicked()), this, SLOT(addFiles()));
    connect(this->ui->playBtn, SIGNAL(clicked()), this, SLOT(playFile()));
    connect(this->ui->pauseBtn, SIGNAL(clicked()), this, SLOT(pauseFile()));
    connect(this->ui->stopBtn, SIGNAL(clicked()), this, SLOT(stopFile()));
    mediaObject = new Phonon::MediaObject(this);
    audioOutput = new Phonon::AudioOutput(this);
    seekSlider = new Phonon::SeekSlider(this);
    Phonon::createPath(mediaObject, audioOutput);
    seekSlider->setMediaObject(mediaObject);
    this->ui->seekLayout->addWidget(seekSlider);
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::changeEvent(QEvent *e)
{
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}
void MainWindow::addFiles(){
    QStringList files = QFileDialog::getOpenFileNames(this, tr("Selec Files to play"));
    QString file;
    foreach(file, files){
        this->ui->listWidget->addItem(file);
        sourceList.append(file);
    }
}
void MainWindow::playFile(){
    if(sourceList.isEmpty()){
        QMessageBox::information(this, tr("no music files"), tr("no files to play"));
        return ;
    }
    mediaObject->setQueue(sourceList);
    mediaObject->play();
    this->ui->playBtn->setEnabled(false);
    this->ui->pauseBtn->setEnabled(true);
}
void MainWindow::pauseFile(){
    mediaObject->pause();
    this->ui->pauseBtn->setEnabled(false);
    this->ui->playBtn->setEnabled(true);
}
void MainWindow::stopFile(){
    mediaObject->stop();
    this->ui->pauseBtn->setEnabled(true);
    this->ui->playBtn->setEnabled(true);
}
 

main.cpp:

view plaincopy to clipboardprint?
#include <QtGui/QApplication>  
#include "mainwindow.h"  
int main(int argc, char *argv[])  
{  
    QApplication a(argc, argv);  
    MainWindow w;  
    w.show();  
    return a.exec();  


本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/jasonblog/archive/2010/02/13/5308197.aspx

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章