QSlider使用笔记

news2024/12/24 11:29:39

最近做项目使用到QSlider滑动条控件,在使用过的过程中,发现一个问题就是点滑动条上的一个位置,滑块并没有移动到鼠标点击的位置,体验感很差,于是研究了下,让鼠标点击后滑块移动到鼠标点击的位置。
1、eventFilter采用事件过滤的方式:
给QSlider安装事件过滤器,重写事件过滤方法:
ui->hSliderAge->installEventFilter(this);

bool Dialog::eventFilter(QObject *watched, QEvent *event)
{
    if(ui->hSliderAge == watched && event->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
        if(mouseEvent->button() == Qt::LeftButton)
        {
            //方法1:
//            int curValue = ui->hSliderAge->maximum() - ui->hSliderAge->minimum();
//            int curPos = ui->hSliderAge->minimum() + curValue*(static_cast<double>(mouseEvent->x()) / ui->hSliderAge->width());
//            ui->hSliderAge->setValue(curPos);
            //方法2:
            int value = QStyle::sliderValueFromPosition(ui->hSliderAge->minimum(), ui->hSliderAge->maximum(), mouseEvent->pos().x(), ui->hSliderAge->width());
            ui->hSliderAge->setValue(value);
        }
    }
    return QDialog::eventFilter(watched, event);
}

运行效果:

这种方式是每个QSlider控件都要写到eventFilter函数里进行处理,如果有多个QSlider控件就会非常混乱,那有没有一种自定义控件的方式来实现这个功能,下面就介绍这种方法。

2、自定义QSlider控件实现点击效果。

#ifndef CUSTOMSLIDER_H
#define CUSTOMSLIDER_H

#include <QSlider>

class CustomSlider : public QSlider
{
    Q_OBJECT
public:
    explicit CustomSlider(QWidget *parent = nullptr);

protected:
    void mousePressEvent(QMouseEvent *event) override;

signals:

};

#endif // CUSTOMSLIDER_H
#include "customslider.h"
#include <QMouseEvent>
#include <QDebug>
#include <QStyle>

CustomSlider::CustomSlider(QWidget *parent)
    : QSlider{parent}
{

}

void CustomSlider::mousePressEvent(QMouseEvent *event)
{
    //获取当前点击位置,得到的这个鼠标坐标是相对于当前QSlider的坐标
    int currentX = event->pos().x();

    //获取当前点击的位置占整个Slider的百分比
    double per = currentX *1.0 / this->width();

    //利用算得的百分比得到具体数字
    int value = per*(this->maximum() - this->minimum()) + this->minimum();
    //int value2 = QStyle::sliderValueFromPosition(this->minimum(), this->maximum(), currentX, this->width());
    //double value3 = per*(this->maximum() - this->minimum()) + this->minimum();
    //设定滑动条位置
    this->setValue(value);

    //滑动条移动事件等事件也用到了mousePressEvent,加这句话是为了不对其产生影响,是的Slider能正常相应其他鼠标事件
    QSlider::mousePressEvent(event);
}

使用:

运行效果:

完整代码如下:

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACE

class Dialog : public QDialog
{
    Q_OBJECT

public:
    Dialog(QWidget *parent = nullptr);
    ~Dialog();
    void initData();

public slots:
    void slotValueChangedSliderAge(int value);
    void slotValueChangedSpinBoxAge(int value);
    void slotValueChangedSlider(int value);
    void slotValueChangedSpinBox(int value);

protected:
    bool eventFilter(QObject *watched, QEvent *event) override;
    bool eventFilter2(QObject *watched, QEvent *event);

private:
    Ui::Dialog *ui;
};
#endif // DIALOG_H
#include "dialog.h"
#include "ui_dialog.h"
#include <QDebug>
#include <QMouseEvent>
#include <QStyle>

Dialog::Dialog(QWidget *parent)
    : QDialog(parent)
    , ui(new Ui::Dialog)
{
    ui->setupUi(this);
    initData();
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::initData()
{
    ui->hSliderAge->installEventFilter(this);
    ui->hSliderAge->setValue(18);
    ui->spinBoxAge->setValue(18);
    //设置步长
    ui->hSliderAge->setSingleStep(4);
    ui->hSlider->setSingleStep(4);
    ui->spinBoxAge->setSingleStep(4);
    ui->spinBox->setSingleStep(4);
    ui->hSliderAge->setRange(0, 115);
    ui->hSlider->setRange(0, 115);
    ui->spinBoxAge->setRange(0, 115);
    ui->spinBox->setRange(0, 115);
    //滑动条托动释放时触发信号
    ui->hSliderAge->setTracking(false);
    ui->hSlider->setTracking(false);
    connect(ui->hSliderAge, SIGNAL(valueChanged(int)), this, SLOT(slotValueChangedSliderAge(int)));
    connect(ui->spinBoxAge, SIGNAL(valueChanged(int)), this, SLOT(slotValueChangedSpinBoxAge(int)));
    connect(ui->hSlider, SIGNAL(valueChanged(int)), this, SLOT(slotValueChangedSlider(int)));
    connect(ui->spinBox, SIGNAL(valueChanged(int)), this, SLOT(slotValueChangedSpinBox(int)));
}

void Dialog::slotValueChangedSliderAge(int value)
{
    ui->spinBoxAge->blockSignals(true);
    ui->spinBoxAge->setValue(value);
    ui->spinBoxAge->blockSignals(false);
}

void Dialog::slotValueChangedSpinBoxAge(int value)
{
    ui->hSliderAge->blockSignals(true);
    ui->hSliderAge->setValue(value);
    ui->hSliderAge->blockSignals(false);
}

void Dialog::slotValueChangedSlider(int value)
{
    ui->spinBox->blockSignals(true);
    ui->spinBox->setValue(value);
    ui->spinBox->blockSignals(false);
}

void Dialog::slotValueChangedSpinBox(int value)
{
    ui->hSlider->blockSignals(true);
    ui->hSlider->setValue(value);
    ui->hSlider->blockSignals(false);
}

bool Dialog::eventFilter(QObject *watched, QEvent *event)
{
    if(ui->hSliderAge == watched && event->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event);
        if(mouseEvent->button() == Qt::LeftButton)
        {
            //方法1:
//            int curValue = ui->hSliderAge->maximum() - ui->hSliderAge->minimum();
//            int curPos = ui->hSliderAge->minimum() + curValue*(static_cast<double>(mouseEvent->x()) / ui->hSliderAge->width());
//            ui->hSliderAge->setValue(curPos);
            //方法2:
//            int value = QStyle::sliderValueFromPosition(ui->hSliderAge->minimum(), ui->hSliderAge->maximum(), mouseEvent->pos().x(), ui->hSliderAge->width());
//            ui->hSliderAge->setValue(value);

            //方法3:
            eventFilter2(watched, event);

        }
    }
    return QDialog::eventFilter(watched, event);
}

bool Dialog::eventFilter2(QObject *watched, QEvent *event)
{
    if(watched == ui->hSliderAge && event->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        //捕获左键按下
        if(mouseEvent->button() == Qt::LeftButton)
        {
            int chunkLen{0};       //滑块宽度
            int sliderLen{0};      //滑槽宽度
            int mousePos{0};       //鼠标按下的位置
            //水平滑动条
            if(ui->hSliderAge->orientation() == Qt::Horizontal)
            {
                chunkLen = ui->hSliderAge->minimumSizeHint().width();
                sliderLen = ui->hSliderAge->width();
                if(ui->hSliderAge->invertedAppearance())
                {
                    mousePos = sliderLen - mouseEvent->x();
                }
                else
                {
                    mousePos = mouseEvent->x();
                }
            }
            else
            {
                //垂直滑动条
                chunkLen = ui->hSliderAge->minimumSizeHint().height();
                sliderLen = ui->hSliderAge->height();
                if(ui->hSliderAge->invertedAppearance())
                {
                    mousePos = sliderLen - mouseEvent->y();
                }
                else
                {
                    mousePos = mouseEvent->y();
                }
            }

            if(sliderLen > chunkLen)
            {
                //计算位置,设置滑动位置
                int curValue = ui->hSliderAge->maximum() - ui->hSliderAge->minimum();
                int sliderPos = ui->hSliderAge->minimum() +
                        (int)(curValue * (mousePos - chunkLen/2.0)/(sliderLen - chunkLen));
                if(ui->hSliderAge->sliderPosition() != sliderPos)
                {
                    ui->hSliderAge->setSliderPosition(sliderPos);
                }
            }
        }
    }

    return QDialog::eventFilter(watched, event);
}

参考:
https://www.cnblogs.com/Gaaagaa/p/12130799.html
https://blog.csdn.net/lion_cxq/article/details/128212132
https://blog.csdn.net/qq_14945437/article/details/98730805

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1430598.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

this指针详细总结 | static关键字 | 静态成员

文章目录 1.this指针引入2.this指针的特性3.静态成员3.1.C语言中static的基本用法3.2.C中的static关键字 1.this指针引入 class student { public:student(const string& name){ _name name; }void print(){// _name<>this->_name<>(*this)._name// 说一下…

【Linux】打包压缩跨系统/网络传输文件常用指令完结

Hello everybody!在今天的文章中我会把剩下的3-4个常用指令讲完&#xff0c;然后开始权限的讲解。那废话不多说&#xff0c;咱们直接进入正题&#xff01; 1.zip/unzip&tar命令 1.zip/unzip 在windows系统中&#xff0c;经常见到带有zip后缀的文件。那个东西就是压缩包。…

携程网首页案例制作

背景线性渐变 语法&#xff1a; background&#xff1a;linear-gradient&#xff08;起始方向&#xff0c;颜色1&#xff0c;颜色2&#xff0c;...&#xff09;&#xff1b; background&#xff1a;-webkit-linear-gradient&#xff08;left&#xff0c;red&#xff0c;blue&a…

使用Python的turtle模块实现简单的烟花效果

import turtle import random import math# 设置窗口大小 width, height 800, 600 screen turtle.Screen() screen.title("Fireworks Explosion") screen.bgcolor("black") screen.setup(width, height)# 定义烟花粒子类 class Particle(turtle.Turtle):…

ES6-let

一、基本语法 ES6 中的 let 关键字用于声明变量&#xff0c;并且具有块级作用域。 - 语法&#xff1a;let 标识符;let 标识符初始值; - 规则&#xff1a;1.不能重复声明let不允许在相同作用域内重复声明同一个变量2.不存在变量提升在同一作用域内&#xff0c;必须先声明才能试…

论文阅读-一种用于大规模分布式文件系统中基于深度强化学习的自适应元数据管理方案

名称&#xff1a; An Adaptive Metadata Management Scheme Based on Deep Reinforcement Learning for Large-Scale Distributed File Systems I. 引言 如今&#xff0c;大型集群文件系统的规模已达到PB甚至EB级别&#xff0c;由此产生的数据呈指数级增长。系统架构师不断设…

算法学习——华为机考题库7(HJ41 - HJ45)

算法学习——华为机考题库7&#xff08;HJ41 - HJ45&#xff09; HJ41 称砝码 描述 现有n种砝码&#xff0c;重量互不相等&#xff0c;分别为 m1,m2,m3…mn &#xff1b; 每种砝码对应的数量为 x1,x2,x3…xn 。现在要用这些砝码去称物体的重量(放在同一侧)&#xff0c;问能称…

STM32--揭秘中断(简易土货版)

抢占优先级响应优先级 视频学习--中断​​​​​​​

数据结构----队列(Queue)的概念、队列的使用、模拟实现队列、循环队列、模拟实现循环队列、双端队列、模拟实现双端队列

文章目录 1 概念2 队列的使用3 队列模拟实现4 循环队列4.1 循环队列 概念4.1 循环队列模拟实现 5. 双端队列 (Deque)6 用队列实现栈7 用栈实现队列 1 概念 队列&#xff1a;只允许在一端进行插入数据操作&#xff0c;在另一端进行删除数据操作的特殊线性表&#xff0c;队列具有…

会计的记账凭证

目录 一. 记账凭证的填制与审核1.1 收付款凭证1.2 转账凭证1.3 单式记账凭证 二. 记账凭证的编号 \quad 一. 记账凭证的填制与审核 \quad \quad 1.1 收付款凭证 \quad 注意︰ 凡是涉及货币资金之间收付款的业务如将库存现金存入银行或从银行提取现金等类经济业务。在实际工作中…

macOS的设置与常用软件(含IntelliJ IDEA 2023.3.2 Ultimate安装,SIP的关闭与开启)

目录 1 系统设置1.1 触控板1.2 键盘 2 软件篇2.1 [科学上网](https://justmysocks5.net/members/)2.1 [安装Chrome浏览器](https://www.google.cn/chrome/index.html)2.2 [安装utools](https://www.u.tools)2.3 [安装搜狗输入法](https://shurufa.sogou.com/)2.4 [安装snipaste…

Qt多语言翻译

Qt多语言翻译概述 Qt提供了非常简单易用的多语言翻译机制&#xff0c;其核心类为QTranslator.概括来说就是利用Qt的lupdate工具将项目中所有tr函数包裹的字符串提取到.ts文件中&#xff0c;然后使用Qt Linguist由专门的翻译人员对提取的.ts文件进行逐个单词短语的翻译工作. 翻译…

MkDocs 部署指南

简介 MkDocs 可以同时编译多个 markdown 文件&#xff0c;形成书籍一样的文件。有多种主题供你选择&#xff0c;很适合项目使用。 MkDocs 是快速&#xff0c;简单和华丽的静态网站生成器&#xff0c;可以构建项目文档。文档源文件在 Markdown 编写&#xff0c;使用单个 YAML …

绝世唐门:霍挂六个十万年魂环,一穿七灭团再现,淘汰赛顺利晋级

Hello,小伙伴们&#xff0c;我是拾荒君。 国漫《斗罗大陆2绝世唐门》第32期超前爆料&#xff0c;霍雨浩开局便释放六个十万年魂环&#xff0c;以绝对的气场碾压天灵学院代表队。首次参与高级魂师大赛&#xff0c;霍雨浩便大放异彩秀出超级霍挂&#xff0c;此等操作就连当初的唐…

2023.12 淘天-数科 已offer

文章目录 岗位信息1面ld 12.17 1H2面 VP 12.18 40min3面 HR 12.2012.21offer薪资方案沟通 岗位信息 1面ld 12.17 1H &#xff08;是一个从业估计很长时间前辈&#xff0c;很平和&#xff0c;感觉能学到很多东西&#xff09; 自我介绍项目深究1.说下自己工作里最有成就感的事和…

【用Unity开发一款横板跳跃游戏部分需要学习的技术点指南】

*** 用Unity开发一款横板跳跃游戏部分需要学习的技术点指南 空洞骑士是一款基于横板平台跳跃的传统风格2D动作冒险游戏&#xff0c;庞大的游戏世界交错相通&#xff0c;玩家控制小虫子去探索幽深黑暗的洞穴&#xff0c;成为了一代人茶余饭后的惦念&#xff0c;深受玩家喜爱。 …

Peter算法小课堂—Dijkstra最短路算法

大家好&#xff0c;我们人见人爱、花见花开、车见车爆胎的Peter Pan来啦&#xff0c;hia~hia~hia。今天&#xff0c;我们今天来学习毒瘤的最短路算法啦。啊这……什么是Dijkstra算法&#xff1f;长文警告⚠ 正经点啊 手算样例 大家思考一下&#xff0c;你在手算样例的时候&am…

MATLAB实现随机森林(RF)回归与自变量影响程度分析

本文分为两部分&#xff0c;首先是对代码进行分段、详细讲解&#xff0c;方便大家理解&#xff1b;随后是完整代码&#xff0c;方便大家自行尝试。另外&#xff0c;关于基于MATLAB的神经网络&#xff08;ANN&#xff09;代码与详细解释&#xff0c;我们将在后期博客中介绍。 1…

Redis常用数据结构与应用场景

常用数据结构 StringHashListSetZset String常用操作 String应用场景 Hash常用操作 hash应用场景 Hash结构优缺点 优点 同类数据归类整合存储,方便数据管理相比String操作消耗内存与spu更小相比string更节省空间 缺点 过期功能不能使用在field上,只用用在key上Redis集群…

Navicate 连接云服务器MySQL

Navicate 连接云服务器MySQL 1.打开Navicate,点击左上角的连接,选择MySQL 第一步:第一个页面是常规,按照图上的标注填写 第二步,点击 SSH ,进入下面的页面 第三步&#xff0c;点击测试连接