需求:我们需要对一个滑动条 滚轮事件 和 点击到滑动条的位置 实时显示
问题:其中在做的时候遇到了很多的问题,一开始感觉很简单,现在将这些问题记录下来
ui图:
问题1:处理QSlider 滚轮事件的时候
这里有很大的问题,但是不知道原因,为什么会出现这样的原因,网上也没搜索到相关的内容
问题描述:我们在打印我们的滑动条的值的时候显示不正确
为了更加清楚显示值的变化,我加了值的显示(这个是测试需要,方便写笔记查看)
boolSliderWidget::eventFilter(QObject* watched, QEvent* event){if(ui.slider == watched){if(event->type()== QEvent::Wheel){
QWheelEvent* wheelEvent =static_cast<QWheelEvent*>(event);
ui.lineEdit1->setText(QString::number(m_index1));
ui.lineEdit2->setText(QString::number(ui.slider->value()));
ui.lineEdit3->setText(QString::number(ui.slider->sliderPosition()));}}returnQWidget::eventFilter(watched, event);}
不知道各位有没有看出这个滑动条的值出现了什么错误:
错误1:当我在向右滑动的时候,滑到最右边的时候,我再向滑动时,滑动条的值是在第10条分割线,上面显示的值: 10 ,实际应该的值:9
错误2:当我继续在向左滑动时,滑动条对应的值 都 对应不上了,上面显示的值 都比原来减少了1
错误3:当我滑动到最左边的时候,我 操控滑动条 从右 再 向左 , 上面的 值竟然从1-》2-》1,实际应该为 2-》1-》0
我的解决办法是:因为刻度总共有11个,通过滑动条 向前 向后 来改变index 的值
boolSliderWidget::eventFilter(QObject* watched, QEvent* event){if(ui.slider == watched){if(event->type()== QEvent::Wheel){//滚轮向前 if(wheelEvent->delta()>0){if(m_index1 >=10){
m_index1 =10;}elseif(m_index1 <10){
m_index1 +=1;}}elseif(wheelEvent->delta()<0){if(m_index1 <=0){
m_index1 =0;}elseif(m_index1 >0){
m_index1 -=1;}}//获取滑动条的值
ui.lineEdit1->setText(QString::number(m_index1));}}returnQWidget::eventFilter(watched, event);}
结果如下:此时我获取的index 值时正确的,因为另外两个参数不是我需要的
问题2:处理QSlider 点击位置事件的时候
问题描述:我发现QSlider点击最后一个刻度的时候,非常的困难,基本上不可能到最后一个刻度(只通过点击的形式,不通过滑动条滚动的形式)
boolSliderWidget::eventFilter(QObject* watched, QEvent* event){if(ui.slider == watched){if(event->type()== QEvent::MouseButtonRelease){//根据鼠标点击的位置 来设置滑动条的 位置
QMouseEvent* mouseEvent =static_cast<QMouseEvent*>(event);if(mouseEvent->button()== Qt::LeftButton){int curValue = ui.slider->maximum()- ui.slider->minimum();int curPos = ui.slider->minimum()+ curValue *(static_cast<double>(mouseEvent->x())/ ui.slider->width());
ui.slider->setValue(curPos);}}}returnQWidget::eventFilter(watched, event);}
效果如下:我们发现 点击最后一个确实非常的困难
解决办法:
boolSliderWidget::eventFilter(QObject* watched, QEvent* event){if(ui.slider == watched){if(event->type()== QEvent::MouseButtonRelease){//根据鼠标点击的位置 来设置滑动条的 位置
QMouseEvent* mouseEvent =static_cast<QMouseEvent*>(event);if(mouseEvent->button()== Qt::LeftButton){int value =QStyle::sliderValueFromPosition(ui.slider->minimum(), ui.slider->maximum(), mouseEvent->pos().x(), ui.slider->width());
ui.slider->setValue(value);}}}returnQWidget::eventFilter(watched, event);}
问题3:因为我的需求是 两个按钮共享一个滑动条,但是 两个 滑动条 有自己对应的index,此时我们就需要设置点击到自己的按钮的时候,设置index值
boolSliderWidget::eventFilter(QObject* watched, QEvent* event){if(ui.slider == watched){if(event->type()== QEvent::Wheel){//滚轮向前 if(wheelEvent->delta()>0){if(m_index1 >=10){
m_index1 =10;}elseif(m_index1 <10){
m_index1 +=1;}}elseif(wheelEvent->delta()<0){if(m_index1 <=0){
m_index1 =0;}elseif(m_index1 >0){
m_index1 -=1;}}//获取滑动条的值
ui.lineEdit1->setText(QString::number(m_index1));qDebug()<<"m_index:"<< m_index1;//既然获取到了正确的m_index1 ,那么我们直接设置值应该没有问题吧(下面两种形式都不行,滑动条滑动的时候 会错乱,导致我们的index 错乱)
ui.slider->setValue((int)m_index1);//ui.slider->setSliderPosition(m_index);}}returnQWidget::eventFilter(watched, event);}voidSliderWidget::on_btn1_clicked(){
ui.slider->setValue(m_index1);}
看一下下面的动图,很明显的就发现了问题
错误1:此时打乱了 我们原本正确的对应滑动条 的index 值,现在获取也不正确了
错误2:我们发现向前滑动一次 然后 向后 滑动一次 ,或者相反;滑动条的值 竟然跳了 2 个间隔,但是我在ui设置的时候只有1个间隔,这是肯定错误的,获取的值肯定是不正确的
解决办法:我就尝试不在事件过滤器里做操作,我在滑动条的ValueChanged事件中做操作
connect(ui.slider,&QSlider::valueChanged,this,[=](int value){
ui.slider->setValue(value);if(ui.btn1->isChecked()){
m_index1 = ui.slider->value();
ui.lineEdit1->setText(QString::number(m_index1));qDebug()<<"m_index1:"<< m_index1;}elseif(ui.btn2->isChecked()){
m_index2 = ui.slider->value();
ui.lineEdit1->setText(QString::number(m_index2));qDebug()<<"m_index2:"<< m_index2;}});
完整代码:
.h文件
#pragmaonce#include<QWidget>#include"ui_SliderWidget.h"#include<QWheelEvent>#include<QDebug>#include<QPoint>#include<QStyle>#include<QSlider>classSliderWidget:publicQWidget{
Q_OBJECT
public:SliderWidget(QWidget* parent = Q_NULLPTR);~SliderWidget();private:booleventFilter(QObject* watched, QEvent* event);public slots:voidon_btn1_clicked();voidon_btn2_clicked();private:
Ui::SliderWidgetClass ui;
quint8 m_index1 =5;
quint8 m_index2 =5;};
.cpp文件
#include"SliderWidget.h"SliderWidget::SliderWidget(QWidget* parent):QWidget(parent){
ui.setupUi(this);
ui.slider->installEventFilter(this);connect(ui.slider,&QSlider::valueChanged,this,[=](int value){
ui.slider->setValue(value);if(ui.btn1->isChecked()){
m_index1 = ui.slider->value();
ui.lineEdit1->setText(QString::number(m_index1));}elseif(ui.btn2->isChecked()){
m_index2 = ui.slider->value();
ui.lineEdit1->setText(QString::number(m_index2));}});}SliderWidget::~SliderWidget(){}boolSliderWidget::eventFilter(QObject* watched, QEvent* event){if(ui.slider == watched){if(event->type()== QEvent::MouseButtonRelease){//根据鼠标点击的位置 来设置滑动条的 位置
QMouseEvent* mouseEvent =static_cast<QMouseEvent*>(event);if(mouseEvent->button()== Qt::LeftButton){//int nDur = ui.slider->maximum() - ui.slider->minimum();//int nPos = ui.slider->minimum() + nDur * (static_cast<double>(mouseEvent->x()) / ui.slider->width());int value =QStyle::sliderValueFromPosition(ui.slider->minimum(), ui.slider->maximum(), mouseEvent->pos().x(), ui.slider->width());
ui.slider->setValue(value);//m_index1 = value;//qDebug() << "m_index:" << m_index1;//qDebug() << "value:" << ui.slider->value();//qDebug() << "nPos:" << nPos;//m_index = value + 1;设定滑动条位置ui.slider->setValue(value);qDebug()<< "position:" << ui.slider->sliderPosition();qDebug() << "value:" << ui.slider->value();m_index = ui.slider->value();//ui.slider->setSliderPosition(value);//qDebug() << "m_index:" << m_index;//qDebug() << "positition:" << ui.slider->sliderPosition();//qDebug() << "value:" << ui.slider->value();//获取当前点击位置,得到的这个鼠标坐标是相对于当前QSlider的坐标//int currentX = mouseEvent->pos().x();////qDebug() <<"currentX:" << currentX;获取当前点击的位置占整个Slider的百分比//double per = currentX * 1.0 / ui.slider->width();//qDebug() <<"width:" << ui.slider->width();利用算得的百分比得到具体数字//int value = per * (ui.slider->maximum() - ui.slider->minimum()) + ui.slider->minimum();////if (value <= 0)//{// value = 0;//}//else if (value >= 10)//{// value = 10;//}//qDebug() << value;//m_index = value;//ui.slider->setValue(value);}}elseif(event->type()== QEvent::Wheel){
QWheelEvent* wheelEvent =static_cast<QWheelEvent*>(event);//static int index = 5;//滚轮向前 if(wheelEvent->delta()>0){if(ui.btn1->isChecked()){if(m_index1 >=10){
m_index1 =10;}elseif(m_index1 <10){
m_index1 +=1;}}elseif(ui.btn2->isChecked()){if(m_index2 >=10){
m_index2 =10;}elseif(m_index2 <10){
m_index2 +=1;}}}elseif(wheelEvent->delta()<0){if(ui.btn1->isChecked()){if(m_index1 <=0){
m_index1 =0;}elseif(m_index1 >0){
m_index1 -=1;}}elseif(ui.btn2->isChecked()){if(m_index2 <=0){
m_index2 =0;}elseif(m_index2 >0){
m_index2 -=1;}}}if(ui.btn1->isChecked()){
ui.lineEdit1->setText(QString::number(m_index1));}elseif(ui.btn2->isChecked()){
ui.lineEdit1->setText(QString::number(m_index2));}//m_index1 = ui.slider->sliderPosition();//ui.lineEdit2->setText(QString::number(ui.slider->value()));//ui.lineEdit3->setText(QString::number(ui.slider->sliderPosition()));//qDebug() << "m_index:" << m_index1;//qDebug() << "value:" << ui.slider->value();//qDebug() << "position:" << ui.slider->sliderPosition();//ui.slider->setValue((int)m_index1);//qDebug() << "value:" << ui.slider->value();//qDebug() << "value:" << ui.slider->value();//ui.slider->setSliderPosition(m_index);//qDebug() << ui.slider->sliderPosition();}}returnQWidget::eventFilter(watched, event);}voidSliderWidget::on_btn1_clicked(){
ui.slider->setValue(m_index1);}voidSliderWidget::on_btn2_clicked(){
ui.slider->setValue(m_index2);}
参考博客:
QSlider设置滚动块定位到鼠标点击的地方
Qt之QSlider介绍(属性设置、信号、实现滑块移动到鼠标点击位置)
Qt滑动条解决点击和拖动问题
版权归原作者 lion_cxq 所有, 如有侵权,请联系我们删除。