【基于QMediaPlayer的简易视频播放器】— 3、结合QSlider实现播放进度控制和音量控制
2016-07-21 16:45
791 查看
基于QMediaPlayer的简易视频播放器
1、创建基本布局2、QMediaPlayer的基本使用
3、结合QSlider实现播放进度控制和音量控制
4、重载QSlider鼠标响应事件,实现单击跳转至任意位置
3、结合QSlider实现播放进度控制和音量控制
3.1 进度控制
QSlider类继承自QAbstractSlider类,可以参考 [ 官方文档 ]其自带的信号如下:
Signal | Description |
---|---|
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鼠标响应事件,实现单击跳转至任意位置]
相关文章推荐
- EntityFramework 入门 CRUD(新增、查询、修改、删除)
- 完美实现跨域Iframe高度自适应【Iframe跨域高度自适应解决方案】
- 常见算法与数据结构整理
- sap中如何配置根据销售订单进行Invoice
- 【杭电oj】1027 - Ignatius and the Princess II(STL - 全排列)
- android TextView中文字通过SpannableString设置属性
- poj 2409 【polya计数】
- Linux Shell中的特殊符号和含义简明总结(包含了绝大部份)
- Volatility 为Centos6.6系统做profile方法
- Unity实现绘制线断二-----用GL画矩形线框
- Android studio基本使用(1)
- FLASH禁止覆盖绝对定位 wmode="opaque"
- 利用OpenCV读取大华网络摄像头
- log4j
- oracle创建job权限
- 项目实战--svn讲解
- 使用Maven搭建Struts2+Spring3+Hibernate4的整合开发环境
- HDU 2303 The Embarrassed Cryptographer(素数筛选+同余定理)
- HttpWebRequest介绍
- sdut 1482 二元多项式