0


QT笔记——QSlider滑动条滚轮事件和点击鼠标位置事件问题

需求:我们需要对一个滑动条 滚轮事件 和 点击到滑动条的位置 实时显示
问题:其中在做的时候遇到了很多的问题,一开始感觉很简单,现在将这些问题记录下来

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滑动条解决点击和拖动问题

标签: qt ui 开发语言

本文转载自: https://blog.csdn.net/lion_cxq/article/details/128212132
版权归原作者 lion_cxq 所有, 如有侵权,请联系我们删除。

“QT笔记——QSlider滑动条滚轮事件和点击鼠标位置事件问题”的评论:

还没有评论