在使用QSlider时了解到它的几个信号槽,以及其可能的实现方式,特此记录,互相学习。
1.QSlider信号
信号 | 信号发射事件 |
---|---|
actionTriggered(int) | 滑块动作时触发,用于告知滑块位置已发生改变,但是对应的数值并未传播及更新,可以通过动作何滑块的值,调用setSliderPosition()来安全地调整任何动作 |
rangeChanged(int, int) | 滑块的最大值或最小值改变时发送此信号, |
sliderMoved(int) | 当用户拖动(按下并滑动)滑块(鼠标滑轮滑动或鼠标点击时此信号不发射) |
sliderPressed() | 当用户按下滑块-不传入按下时滑块值 |
sliderReleased() | 当用户释放滑块-不传入释放时滑块值 |
valueChanged(int) | 当滑块的值发生了改变 |
以上信号继承于QAbstractSlider,在使用时发现如果鼠标点击了滑块的某一处,其值并不会直接滑动到鼠标点击位置,而是一段段的移动,后来查看了QSlider的头文件,看到文件中重写了鼠标操作函数,于是想着写一个继承QSlider的类实现需要的功能。
2.文件结构
- 工程文件 —— RSlider.pro
- 头文件 —— mainwindow.h、rslider.h(继承QSlider的RSlider类头文件)
- 源文件 —— main.cpp、mainwindow.cpp、rslider.cpp(RSlider类源文件)
- 界面文件 —— mainwindow.ui
3.主要代码
实现的主要步骤是创建继承QSlider的类、在新类中重写鼠标点击/释放函数、将控件提升。
因未找到表示QSlider是横向还是纵向的标示,所以此文仅以横向Slider进行说明。(个人目前能想到的区分横纵向的方法是比较其宽高,即其width()和height(),如果宽度较大则为横向,反之则为纵向,有其他更准确或方便的方法还望留言赐教)
1. 创建继承QSlider的类
rslider.h
#include <QSlider>
#include <QMouseEvent>
#include <QWidget>
#include <QDebug>
class RSlider : public QSlider
{
Q_OBJECT
public:
explicit RSlider(QWidget *parent = 0);
~RSlider();
signals:
void rSliderValueManulChange(int mValue);
protected:
void mousePressEvent(QMouseEvent *ev);
void mouseReleaseEvent(QMouseEvent *ev);
};
2. 重写鼠标按下/释放函数
rslider.cpp
#include "rslider.h"
RSlider::RSlider(QWidget *parent) : QSlider(parent)
{
}
RSlider::~RSlider()
{
}
void RSlider::mousePressEvent(QMouseEvent *ev)
{
QSlider::mousePressEvent(ev);//调用父类的鼠标点击处理事件,这样可以不影响拖动的情况
double pos = ev->pos().x() / (double)width();//获取按下时相对滑动条所在的比例
double value = pos * (maximum() - minimum()) + minimum();//计算按下时的位置
if(value > maximum())
{
value = maximum();
}
if(value < minimum())
{
value = minimum();
}
int mValue = value + 0.5;//四舍五入
setValue(mValue);
emit rSliderValueManulChange(mValue);//发送输出信号
}
void RSlider::mouseReleaseEvent(QMouseEvent *ev)
{
QSlider::mouseReleaseEvent(ev);
double pos = ev->pos().x() / (double)width();
double value = pos * (maximum() - minimum()) + minimum();
if(value > maximum())
{
value = maximum();
}
if(value < minimum())
{
value = minimum();
}
int mValue = value + 0.5;
setValue(mValue);
emit rSliderValueManulChange(mValue);
}
3.将使用的QSlider提升为自己创建的类RSlider
选择使用的QSlider,右键点击选择将其提升为RSlider。
4.进行继承类的信号的槽连接
mainwindow.cpp
将提升后的Slider控件进行信号和槽函数的连接,然后按下或释放后会执行对应的槽函数,在槽函数中可以对更改后的数值进行赋值等操作。
#include "rslider.h"
connect(ui->slider, SIGNAL(rSliderValueManulChange(int)), this, SLOT(sliderValue(int)));
如果需要实现其他的功能,可将其他的鼠标操作及滑轮(QWheelEvent)操作函数进行重写。
4.Tips:
- pageStep属性:表示滑轮上/下滑一次或者鼠标左键在滑动条上某处位置(非当前所处位置)点击一次变化的数值。
- valueChanged这个信号会在滑动条数值变化时便发出,程序内更改也会发送;为避免重复调用可用以下方法:一:添加不同情况下值改变时的状态标志;二:手动添加信号槽连接(connect),槽函数为自己命名的函数名(其他人分享参考,还未验证)。三:重写鼠标滑轮事件函数,创建窗口操作时值变化的信号并进行信号槽的连接。
5.参考内容
- https://www.cnblogs.com/LaoYuanPython/p/13643546.html
- https://blog.csdn.net/potato123232/article/details/119040325
欢迎评论区评论或私信交流。