QT之QSlider重写鼠标事件

在使用QSlider时了解到它的几个信号槽,以及其可能的实现方式,特此记录,互相学习。

1.QSlider信号

信号信号发射事件
actionTriggered(int)滑块动作时触发,用于告知滑块位置已发生改变,但是对应的数值并未传播及更新,可以通过动作何滑块的值,调用setSliderPosition()来安全地调整任何动作
rangeChanged(int, int)滑块的最大值或最小值改变时发送此信号,
sliderMoved(int)当用户拖动(按下并滑动)滑块(鼠标滑轮滑动或鼠标点击时此信号不发射
sliderPressed()当用户按下滑块-不传入按下时滑块值
sliderReleased()当用户释放滑块-不传入释放时滑块值
valueChanged(int)当滑块的值发生了改变

以上信号继承于QAbstractSlider,在使用时发现如果鼠标点击了滑块的某一处,其值并不会直接滑动到鼠标点击位置,而是一段段的移动,后来查看了QSlider的头文件,看到文件中重写了鼠标操作函数,于是想着写一个继承QSlider的类实现需要的功能。

2.文件结构

  1. 工程文件 —— RSlider.pro
  2. 头文件 —— mainwindow.h、rslider.h(继承QSlider的RSlider类头文件)
  3. 源文件 —— main.cpp、mainwindow.cpp、rslider.cpp(RSlider类源文件)
  4. 界面文件 —— 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:

  1. pageStep属性:表示滑轮上/下滑一次或者鼠标左键在滑动条上某处位置(非当前所处位置)点击一次变化的数值。
  2. valueChanged这个信号会在滑动条数值变化时便发出,程序内更改也会发送;为避免重复调用可用以下方法:一:添加不同情况下值改变时的状态标志;二:手动添加信号槽连接(connect),槽函数为自己命名的函数名(其他人分享参考,还未验证)。三:重写鼠标滑轮事件函数,创建窗口操作时值变化的信号并进行信号槽的连接。

5.参考内容

  1. https://www.cnblogs.com/LaoYuanPython/p/13643546.html
  2. https://blog.csdn.net/potato123232/article/details/119040325

欢迎评论区评论或私信交流。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值