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


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

    ui图:
    在这里插入图片描述
    在这里插入图片描述

    问题1:处理QSlider 滚轮事件的时候
    这里有很大的问题,但是不知道原因,为什么会出现这样的原因,网上也没搜索到相关的内容

    问题描述:我们在打印我们的滑动条的值的时候显示不正确
    为了更加清楚显示值的变化,我加了值的显示(这个是测试需要,方便写笔记查看)

    bool SliderWidget::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()));
    		}
    	}
    	return QWidget::eventFilter(watched, event);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    不知道各位有没有看出这个滑动条的值出现了什么错误:
    在这里插入图片描述
    错误1:当我在向右滑动的时候,滑到最右边的时候,我再向滑动时,滑动条的值是在第10条分割线,上面显示的值: 10 ,实际应该的值:9
    错误2:当我继续在向左滑动时,滑动条对应的值 都 对应不上了,上面显示的值 都比原来减少了1
    错误3:当我滑动到最左边的时候,我 操控滑动条 从右 再 向左 , 上面的 值竟然从1-》2-》1,实际应该为 2-》1-》0

    我的解决办法是:因为刻度总共有11个,通过滑动条 向前 向后 来改变index 的值

    bool SliderWidget::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;
    				}
    				else if (m_index1 < 10)
    				{
    					m_index1 += 1;
    				}
    			}
    			else if (wheelEvent->delta() < 0)
    			{
    				if (m_index1 <= 0)
    				{
    					m_index1 = 0;
    				}
    				else if (m_index1 > 0)
    				{
    					m_index1 -= 1;
    				}
    			}
    			
    			//获取滑动条的值
    			ui.lineEdit1->setText(QString::number(m_index1));
    		}
    	}
    	return QWidget::eventFilter(watched, event);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    结果如下:此时我获取的index 值时正确的,因为另外两个参数不是我需要的
    在这里插入图片描述
    问题2:处理QSlider 点击位置事件的时候
    问题描述:我发现QSlider点击最后一个刻度的时候,非常的困难,基本上不可能到最后一个刻度(只通过点击的形式,不通过滑动条滚动的形式)

    bool SliderWidget::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);
    			}
    		}
    	}
    	return QWidget::eventFilter(watched, event);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    效果如下:我们发现 点击最后一个确实非常的困难
    在这里插入图片描述
    解决办法:

    bool SliderWidget::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);
    			}
    		}
    	}
    	return QWidget::eventFilter(watched, event);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述
    问题3:因为我的需求是 两个按钮共享一个滑动条,但是 两个 滑动条 有自己对应的index,此时我们就需要设置点击到自己的按钮的时候,设置index值

    bool SliderWidget::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;
    				}
    				else if (m_index1 < 10)
    				{
    					m_index1 += 1;
    				}
    			}
    			else if (wheelEvent->delta() < 0)
    			{
    				if (m_index1 <= 0)
    				{
    					m_index1 = 0;
    				}
    				else if (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);
    		}
    	}
    	return QWidget::eventFilter(watched, event);
    }
    
    void SliderWidget::on_btn1_clicked()
    {
    	ui.slider->setValue(m_index1);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    看一下下面的动图,很明显的就发现了问题
    在这里插入图片描述
    错误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;
    		}
    		else if (ui.btn2->isChecked())
    		{
    			m_index2 = ui.slider->value();
    			ui.lineEdit1->setText(QString::number(m_index2));
    			qDebug() << "m_index2:" << m_index2;
    		}
    		
    	});
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述
    完整代码:
    .h文件

    #pragma once
    
    #include 
    #include "ui_SliderWidget.h"
    #include 
    #include 
    #include 
    #include 
    #include 
    
    class SliderWidget : public QWidget
    {
    	Q_OBJECT
    
    public:
    	SliderWidget(QWidget* parent = Q_NULLPTR);
    	~SliderWidget();
    
    private:
    	bool eventFilter(QObject* watched, QEvent* event);
    
    public slots:
    	void on_btn1_clicked();
    	void on_btn2_clicked();
    
    private:
    	Ui::SliderWidgetClass ui;
    	quint8 m_index1 = 5;
    	quint8 m_index2 = 5;
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    .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));
    		}
    		else if (ui.btn2->isChecked())
    		{
    			m_index2 = ui.slider->value();
    			ui.lineEdit1->setText(QString::number(m_index2));
    		}
    		
    	});
    }
    
    SliderWidget::~SliderWidget()
    {
    }
    
    bool SliderWidget::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(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);
    
    			}
    		}
    		else if (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;
    					}
    					else if (m_index1 < 10)
    					{
    						m_index1 += 1;
    					}
    				}
    				else if (ui.btn2->isChecked())
    				{
    					if (m_index2 >= 10)
    					{
    						m_index2 = 10;
    					}
    					else if (m_index2 < 10)
    					{
    						m_index2 += 1;
    					}
    				}
    
    			}
    			else if (wheelEvent->delta() < 0)
    			{
    				if (ui.btn1->isChecked())
    				{
    					if (m_index1 <= 0)
    					{
    						m_index1 = 0;
    					}
    					else if (m_index1 > 0)
    					{
    						m_index1 -= 1;
    					}
    				}
    				else if (ui.btn2->isChecked())
    				{
    					if (m_index2 <= 0)
    					{
    						m_index2 = 0;
    					}
    					else if (m_index2 > 0)
    					{
    						m_index2 -= 1;
    					}
    				}
    
    			}
    			if (ui.btn1->isChecked())
    			{
    				ui.lineEdit1->setText(QString::number(m_index1));
    			}
    			else if (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();
    
    		}
    	}
    
    	return QWidget::eventFilter(watched, event);
    }
    
    void SliderWidget::on_btn1_clicked()
    {
    	ui.slider->setValue(m_index1);
    }
    
    void SliderWidget::on_btn2_clicked()
    {
    	ui.slider->setValue(m_index2);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
    • 137
    • 138
    • 139
    • 140
    • 141
    • 142
    • 143
    • 144
    • 145
    • 146
    • 147
    • 148
    • 149
    • 150
    • 151
    • 152
    • 153
    • 154
    • 155
    • 156
    • 157
    • 158
    • 159
    • 160
    • 161
    • 162
    • 163
    • 164
    • 165
    • 166
    • 167
    • 168
    • 169
    • 170
    • 171
    • 172
    • 173
    • 174
    • 175
    • 176
    • 177
    • 178
    • 179
    • 180

    参考博客:
    QSlider设置滚动块定位到鼠标点击的地方
    Qt之QSlider介绍(属性设置、信号、实现滑块移动到鼠标点击位置)
    Qt滑动条解决点击和拖动问题

  • 相关阅读:
    Headscale组网教程
    秋招每日一题T25——最少交换次数
    斯坦福机器学习 Lecture2 (假设函数、参数、样本等等术语,还有批量梯度下降法、随机梯度下降法 SGD 以及它们的相关推导,还有正态方程)
    ElasticSearch DSL与java API示例
    Vue事件修饰符的使用
    【每日一题】50. Pow(x, n)
    牛客-946B-筱玛爱阅读
    从0开始python学习-53.python中flask创建简单接口
    你好,我的新名字叫 “铜锁 / Tongsuo”
    【深入浅出React和Redux】读书笔记二:设计高质量的React组件
  • 原文地址:https://blog.csdn.net/lion_cxq/article/details/128212132