您的位置:首页 > 其它

【基于QMediaPlayer的简易视频播放器】— 3、结合QSlider实现播放进度控制和音量控制

2016-07-21 16:45 791 查看

基于QMediaPlayer的简易视频播放器

1、创建基本布局

2、QMediaPlayer的基本使用

3、结合QSlider实现播放进度控制和音量控制

4、重载QSlider鼠标响应事件,实现单击跳转至任意位置

3、结合QSlider实现播放进度控制和音量控制

3.1 进度控制

QSlider类继承自QAbstractSlider类,可以参考 [ 官方文档 ]

其自带的信号如下:

SignalDescription
valueChanged()当进度值改变时触发
sliderPressed()当用户按下滑块时触发
sliderMoved()当用户拖动滑块时触发
sliderMoved()当用户释放滑块时触发
对于播放器来说,其进度条应该有两种控制方式,一是拖动,二是点击。

其中我们需要用到sliderMoved()和sliderReleased()两种信号来实现拖动功能,

对于点击,QSlider的mousePressEvent()默认的方式是,点击之后跳跃一定的固定距离,无法实现“指哪打哪”,因此我们需要对mousePressEvent()进行重写。具体方法将在下一篇文章中介绍。

首先在ui载入时将Slider禁用,等到文件载入时才启用。然后连接三组信号槽,第一组是由重载的mousePressEvent事件发送的,为避免混淆换了个costomSliderClicked的名字。其余两组是QSlider自带的sliderMoved和sliderReleased信号。

MediaPlayer::MediaPlayer(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MediaPlayer)
{
ui->setupUi(this);
ui->pushButton_play_and_pause->setEnabled(false);
ui->pushButton_volume->setEnabled(false);

ui->slider_progress->setEnabled(false);
connect(ui->slider_progress,&CustomSlider::costomSliderClicked,this,&MediaPlayer::slider_progress_clicked);
connect(ui->slider_progress,&CustomSlider::sliderMoved,this,&MediaPlayer::slider_progress_moved);
connect(ui->slider_progress,&CustomSlider::sliderReleased,this,&MediaPlayer::slider_progress_released);
}


首先我们需要配合定时器QTimer实现Slider随播放进度而移动。

之所以选择QTimer,而不是player的positionChanged信号来驱动,是因为positionChange和后面要用的QSlider两个信号槽互相修改,容易出现冲突。

添加QTimer头文件,并定义全局变量

#include <QTimer>

//与Slider有关的播放控制变量
QTimer * timer;
int maxValue = 1000;//设置进度条的最大值


在on_pushButton_open_file_clicked槽函数中添加Slider和Timer的相关代码,并将timer连接至onTimerOut槽函数:

void MediaPlayer::on_pushButton_open_file_clicked()
{
//前面部分代码与第2篇中相同//
//启用slider并设置范围
ui->slider_progress->setEnabled(true);
ui->slider_progress->setRange(0,maxValue);

timer = new QTimer();
timer->setInterval(1000);
timer->start();
//将timer连接至onTimerOut槽函数
connect(timer, SIGNAL(timeout()), this, SLOT(onTimerOut()));
}


添加定时器的槽函数onTimerOut(),其原理就是根据一定的间隔(本例中为1000ms)刷新Slider的值,这个值是根据播放器player的position(当前位置)和duration(总时长)计算出来的:

void MediaPlayer::onTimerOut()
{
ui->slider_progress->setValue(player->position()*maxValue/player->duration());
}


到这里就实现了Slider随进度移动的功能,接下来添加控制代码。

三个槽函数分别对应单击、拖动和释放。在拖动过程中,可以先暂停计时器,等用户拖动完成释放之后,再重启定时器。这样防止用户在拖动过程中滑块依然按照定时器触发进行移动,瞎跳,闹心。

void MediaPlayer::slider_progress_clicked()
{
player->setPosition(ui->slider_progress->value()*player->duration()/maxValue);
}

void MediaPlayer::slider_progress_moved()
{
//暂时停止计时器,在用户拖动过程中不修改slider的值
timer->stop();
player->setPosition(ui->slider_progress->value()*player->duration()/maxValue);
}

void MediaPlayer::slider_progress_released()
{
//用户释放滑块后,重启定时器
timer->start();
}


3.2 音量控制

音量控制的方法与进度控制非常相似,可以直接使用重载后的CustomSlider类。这里我们不在Designer中拖入控件,而是通过手动实现的方式来添加音量控制的Slider。

首先在mediaplayer.cpp的构造函数中继续添加初始化内容

MediaPlayer::MediaPlayer(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MediaPlayer)
{
/*与上述相同*/
/*
……
*/
//手动设置slider_volume 包括初始化 方向 禁用,以及槽函数
slider_volume = new CustomSlider(this);
slider_volume->setOrientation(Qt::Vertical);
slider_volume->setEnabled(false);
slider_volume->hide();
//由于不涉及到slider值的刷新,因此只需对move和自定义click两个信号进行处理,并且可以共用一个槽函数
connect(slider_volume,&CustomSlider::costomSliderClicked,this,&MediaPlayer::slider_volume_changed);
connect(slider_volume,&CustomSlider::sliderMoved,this,&MediaPlayer::slider_volume_changed);

}


槽函数

//音量控制Slider的槽函数
void MediaPlayer::slider_volume_changed()
{
player->setVolume(slider_volume->value());
}


音量控制按钮的槽函数,通过hide()和show()方法,实现音量控制Slider的唤出和收起

bool state_slider_volume = false;
void MediaPlayer::on_pushButton_volume_clicked()
{
if(state_slider_volume)
{
slider_volume->hide();
}
else
{
slider_volume->setValue(player->volume());
//计算位置,使其位于音量控制按钮的上方
slider_volume->setGeometry(QRect(ui->pushButton_volume->pos().rx()+0.5*ui->pushButton_volume->width()-15, ui->pushButton_volume->y()-100 , 30, 102));
slider_volume->show();
}
state_slider_volume = !state_slider_volume;
}


其效果如图



到这里,QSlider的移动与控制功能就已经完成了,但是实际上我们需要重载QSlider的mousePressEvent以实现指哪打哪的效果,因此需要继承一个新类CustomSlider,详情见第4篇

[ 重载QSlider鼠标响应事件,实现单击跳转至任意位置]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: