最近的项目需要利用QSlider水平进度条,实现鼠标控制音乐播放的进度。但是QSlider 本身没有抛出捕捉鼠标事件,获取鼠标的x方向位置信息的信号,所以为了实现功能,我们需要对QSlider重写自定义类。
QSlider类所抛出的信号:
valueChanged():当滑块的值发生了改变,发射此信号。tracking()确定在用户交互时,是否发出此信号。
sliderPressed():当用户按下滑块,发射此信号。
sliderMoved():当用户拖动滑块,发射此信号。
sliderReleased():当用户释放滑块,发射此信号。
重写QSlider类:
- 新建MySlider 自定义Qt类,继承自QSlider。
2. 头文件myslider.h
class MySlider : public QSlider
{
Q_OBJECT
public:
MySlider(QWidget *parent = 0);
~MySlider();
Q_SIGNALS:
void sliderReleasedAt(int);//当鼠标释放时,抛出包含鼠标X坐标位置信息的信号
public Q_SLOTS:
//void setValue(int value);
protected: //mouse
void mousePressEvent(QMouseEvent *event); //单击
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event) ;
// virtual bool event(QEvent *event) override;
bool m_isMoving;
int m_value;
bool m_mousePress;
};
// MYSLIDER_H
3. CPP文件重写方法myslider.cpp
MySlider::MySlider(QWidget *parent):QSlider(parent){
m_value=0;
m_mousePress = false;
m_isMoving=false;
}
MySlider::~MySlider()
{
}
void MySlider::mousePressEvent(QMouseEvent *event){
// this.x:控件原点到界面边缘的x轴距离;
// globalPos.x:鼠标点击位置到屏幕边缘的x轴距离;
// pos.x:鼠标点击位置到本控件边缘的距离;
// this.width:本控件的宽度;
//注意应先调用父类的鼠标点击处理事件,这样可以不影响拖动的情况
QSlider::mousePressEvent(event);
m_isMoving = false;
m_mousePress = true;
//获取鼠标的位置,这里并不能直接从ev中取值(因为如果是拖动的话,鼠标开始点击的位置没有意义了)
double pos = event->pos().x() / (double)width();
double value = pos * (maximum() - minimum()) + minimum();
//value + 0.5 四舍五入
if(value>maximum()){
value=maximum();
}
if(value<minimum()){
value=minimum();
}
m_value=value+0.5;
setValue(m_value);
//emit sliderMoved( m_value );
//向父窗口发送自定义事件event type,这样就可以在父窗口中捕获这个事件进行处理
QEvent evEvent(static_cast<QEvent::Type>(QEvent::User + 1));
QCoreApplication::sendEvent(parentWidget(), &evEvent);
}
void MySlider::mouseMoveEvent(QMouseEvent *event){
QSlider::mouseMoveEvent(event);
//qDebug()<<"mouseMoveEvent";
double pos = event->pos().x() / (double)width();
double value = pos * (maximum() - minimum()) + minimum();
if(value>maximum()){
value=maximum();
}
if(value<minimum()){
value=minimum();
}
//value + 0.5 四舍五入
if(m_mousePress){
m_value=value + 0.5;
m_isMoving=true;
//emit sliderMoved(m_value);
}
setValue(value + 0.5);
//向父窗口发送自定义事件event type,这样就可以在父窗口中捕获这个事件进行处理
QEvent evEvent(static_cast<QEvent::Type>(QEvent::User + 1));
QCoreApplication::sendEvent(parentWidget(), &evEvent);
}
void MySlider::mouseReleaseEvent(QMouseEvent *event){
QSlider::mouseReleaseEvent(event);
//qDebug()<<"mouseReleaseEvent"<<m_value;
m_mousePress = false;
m_isMoving=false;
emit sliderReleasedAt(m_value);//抛出有用信号
}
- myslider.ui自己设计一下
- 将主UI界面中QSlider控件提升为MySlider类