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

基于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鼠标响应事件,实现单击跳转至任意位置]

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值