第15篇 Qt实现简单音乐播放器(二)
1.实现播放
#include <QMediaPlayer>
为了能够实现播放音乐,那么我们要加入这个头问件,而加入这个头文件,要得在项目文件(.pro)中加入:QT += multimedia
private:
QMediaPlayer* player;//播放者
QString musicpath;//音乐路径
bool isplay = false;//判断歌曲是否正在播放
再者我们除了加播放者之外,还需要一个QString对象保存音乐的路径,在很多地方会用到,bool变量记录歌曲是否正在播放,在暂停和播放时用到。
1.1.各个槽函数
1.1.1.播放者player
(1)信号
this->player = new QMediaPlayer;
QObject::connect(this->player,SIGNAL(positionChanged(qint64)),
this,SLOT(on_player_positionChanged(qint64)));//歌曲的当前播放位置改变
QObject::connect(this->player,SIGNAL(durationChanged(qint64)),
this,SLOT(on_player_durationChanged(qint64)));//整首歌的持续时间
QMediaPlayer对象会发出positionChanged(qint64)和durationChanged(qint64)信号(当然还有其他信号,但这里不需要)。
第一个信号是歌曲播放进度位置改变,比如播放到了2分4秒,不过它不是以秒计时,而是以毫秒计时,所以发出的信号中有qint64变量表示当前进度。
第二个信号是返回当前歌曲的总持续时长(歌曲改变的时候发出),比如这首歌有5分40秒,则其发出信号值中有qint64变量表示的总时长。
(2)槽函数on_player_positionChanged(qint64 position)
void MusicPlaying::on_player_positionChanged(qint64 position)
{
if(this->timeprogress->isSliderDown()){
return ;
}
this->timeprogress->setSliderPosition(position);
int secs = position / 1000;
int mins = secs / 60;
secs = secs % 60;
this->currenttime->setText(QString::asprintf("%02d:%02d",mins,secs));
if(this->player->position() == this->player->duration() &&
this->player->position() != 0 && this->player->duration() != 0){
on_nextsong_clicked();
}
}
很简单,第一句判断是判断如果它到了末尾就直接返回,否则就执行下面的操作,首先是设置进度条的位置,然后计算当前歌曲的时间位置,即播放到了哪里,然后再显示在QLabel中,最后判断是否已经结束。
(3)槽函数on_player_durationChanged(qint64 duration)
void MusicPlaying::on_player_durationChanged(qint64 duration)
{
this->timeprogress->setMaximum(duration);//设置进度条最大值为当前音乐总进度
int secs = duration/1000;
int mins = secs/60;
secs = secs % 60;
this->durationstime->setText(QString::asprintf("%02d:%02d",mins,secs));
}
首先设置进度条的最大值,然后计算出歌曲的总时长,显示在QLabel中。
1.1.2.音乐列表musiclistWidget
(1)信号
this->musiclistWidget = new QListWidget;//所有音乐列表显示
QObject::connect(this->musiclistWidget,SIGNAL(currentRowChanged(int)),
this,SLOT(on_musiclistWidget_currentRowChanged(int)));
当列表里当前选中行发生改变是发出该信号,比如当前行为第一行,我们点击第三行,那么选中的是第三行,即当前行变为第三行,播放第三行歌曲。
(2)槽函数on_musiclistWidget_currentRowChanged(int currentrow)
void MusicPlaying::on_musiclistWidget_currentRowChanged(int currentrow)
{
this->currentmusic->setText(this->musiclistWidget->item(currentrow)->text());
player->setMedia(QUrl::fromLocalFile(musicpath+'/'+this->musiclistWidget->item(currentrow)->text()));
player->setVolume(this->volumeprogress->value());
player->play();
this->isplay = true;
}
首先即是显示当前歌曲名,然后播放当前歌曲。
1.1.3.时间进度timeprogress
(1)信号
this->timeprogress = new QSlider;//时间进度
QObject::connect(this->timeprogress,SIGNAL(sliderMoved(int)),
this,SLOT(on_timeprogress_sliderMoved(int)));
这个信号是在我们用鼠标拖动滑块时发出,拖到哪歌曲就走到哪。
(2)槽函数on_timeprogress_sliderMoved(int position)
void MusicPlaying::on_timeprogress_sliderMoved(int position)
{
player->setPosition(position);//如果滑块改变位置,则改变音乐进度
int secs = position / 1000;
int mins = secs / 60;
secs = secs % 60;
this->currenttime->setText(QString::asprintf("%02d:%02d",mins,secs));
if(this->player->position() == this->player->duration() &&
this->player->position() != 0 && this->player->duration() != 0){
on_nextsong_clicked();
}
}
设置歌曲当前位置,再计算出时间,显示出来。
1.1.4.上一首lastsong
(1)信号
this->lastsong = new QPushButton("上一首");
QObject::connect(this->lastsong,SIGNAL(clicked()),this,SLOT(on_lastsong_clicked()));
上一曲按钮被点击。
(2)槽函数on_lastsong_clicked()
void MusicPlaying::on_lastsong_clicked()
{
int currentrow = this->musiclistWidget->currentRow();
int rowcount = this->musiclistWidget->count();
this->musiclistWidget->setCurrentRow((currentrow - 1 + rowcount) % rowcount);
}
要实现上一曲只需改变当前选中行即可,因为改变了当前选中行,会发出信号,播放当前选中行的歌曲。为了能够实现当当前选中行为第一行时,点上一曲回到最后一行,方式为(currentrow - 1 + rowcount) % rowcount;
1.1.5.暂停、播放playpause
(1)信号
this->playpause = new QPushButton("暂停/播放");
QObject::connect(this->playpause,SIGNAL(clicked()),this,SLOT(on_playpause_clicked()));
按钮被点击。
(2)槽函数
void MusicPlaying::on_playpause_clicked()
{
if(isplay){
this->player->pause();
this->isplay = false;
}
else{
this->player->play();
this->isplay = true;
}
}
如果歌曲在播放,则暂停;若果歌曲在暂停,则播放。
1.1.6.下一首nextsong
(1)信号
this->nextsong = new QPushButton("下一首");
QObject::connect(this->nextsong,SIGNAL(clicked()),this,SLOT(on_nextsong_clicked()));
(2)槽函数on_nextsong_clicked()
void MusicPlaying::on_nextsong_clicked()
{
int currentrow = this->musiclistWidget->currentRow();
int rowcount = this->musiclistWidget->count();
this->musiclistWidget->setCurrentRow((currentrow + 1) % rowcount);
}
和上一曲差不多的,区别在于(currentrow + 1) % rowcount;
1.1.7.音量进度volumeprogress
(1)信号
this->volumeprogress = new QSlider;//音量进度
QObject::connect(this->volumeprogress,SIGNAL(valueChanged(int)),
this,SLOT(on_volumeprogress_valueChanged(int)));
(2)槽函数on_volumeprogress_valueChanged(int value)
void MusicPlaying::on_volumeprogress_valueChanged(int value)
{
player->setVolume(value);
this->currentvolume->setText(QString::asprintf("%d",value));
}
设置音量,显示音量。
2.结语
先到这。