QSlider使用笔记

最近做项目使用到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_NAMESPACEclass Dialog : public QDialog
{Q_OBJECTpublic: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.mzph.cn/news/667401.shtml

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

相关文章

node-sass版本与NodeJS版本不匹配的问题

npm install 报错如下 npm ERR! code 1 npm ERR! path D:\Project\git_Product\YYYY\user\node_modules\node-sass npm ERR! command failed npm ERR! command C:\WINDOWS\system32\cmd.exe /d /s /c node scripts/build.js 问题原因 node-sass 与 node 版本不匹配 卸载Node…

【计算机图形学】实验二 用扫描线算法实现多边形填充

&#x1f57a;作者&#xff1a; 主页 我的专栏C语言从0到1探秘C数据结构从0到1探秘Linux &#x1f618;欢迎关注&#xff1a;&#x1f44d;点赞&#x1f64c;收藏✍️留言 &#x1f3c7;码字不易&#xff0c;你的&#x1f44d;点赞&#x1f64c;收藏❤️关注对我真的很重要&…

9.SELinux

目录 1. 概述 1.1. 概念 1.2. 作用&#xff1a; 1.3. SELinux与传统的权限区别 2. SELinux工作原理 2.1. 名词解释 2.1.1. 主体&#xff08;Subject&#xff09; 2.1.2. 目标&#xff08;Object&#xff09; 2.1.3. 策略&#xff08;Policy&#xff09; 2.1.4. 安全上…

详解Redis哨兵模式下,主节点掉线而重新选取主节点的流程

⭐最核心的结论&#xff1a;所谓选举的过程不是直接选出新的主节点&#xff0c;而是先在哨兵节点中选出 leader &#xff0c;再由 leader 负责后续主节点的指定。 假定当前环境&#xff1a; 三个哨兵(sentenal1, sentenal2, sentenal3)一个主节点(redis-master)两个从节点(red…

接口测试框架对比

公司计划系统的开展接口自动化测试&#xff0c;需要我这边调研一下主流的接口测试框架给后端测试&#xff08;主要测试接口&#xff09;的同事介绍一下每个框架的特定和使用方式。后端同事根据他们接口的特点提出一下需求&#xff0c;看哪个框架更适合我们。 需求 1、接口编写…

端到端实现高精地图重建(TopoNet解读和横评)

论文出处 [2304.05277] Graph-based Topology Reasoning for Driving Scenes (arxiv.org)https://arxiv.org/abs/2304.05277 TopoNet TopoNet的目标是从车辆上安装的多视角摄像头获取图像&#xff0c;感知实体并推理出驾驶场景的拓扑关系&#xff0c;实现端到端预测&#xf…

【自动化测试】----Java的单元测试工具Junit5

目录 支持Java的最低版本为8在pom.xml添加依赖Junit提供的注解功能 断言 Assertion类提供的一些方法测试用例执行顺序 &#xff08;为了预防测试用例执行顺序错误&#xff09;参数化 &#xff08;假设登陆操作&#xff0c;用户名和密码很多&#xff0c;尽可能通过一个测试用例…

Java多线程--JDK5.0新增线程创建方式

文章目录 一、新增方式1&#xff1a;实现Callable接口&#xff08;1&#xff09;介绍&#xff08;2&#xff09;案例&#xff08;3&#xff09;总结对比 二、新增方式2&#xff1a;使用线程池&#xff08;1&#xff09;问题与解决思路1、现有问题2、解决思路3、好处 &#xff0…

Swift Vapor 教程(查询数据、插入数据)

上一篇简单写了 怎么创建 Swift Vapor 项目以及在开发过程中使用到的软件。 这一篇写一个怎么在创建的项目中创建一个简单的查询数据和插入数据。 注&#xff1a;数据库配置比较重要 先将本地的Docker启动起来&#xff0c;用Docker管理数据库 将项目自己创建的Todo相关的都删掉…

以小猪o2o生活通v17.1为例简要分析SWOOLE加密破解,swoole_loader加密破解swoole加密逆向后的代码修复流程(个人见解高手掠过)

现在用Php加密五花八门除了组件就是混淆&#xff0c;在组件里面响当当的还属swoole&#xff0c;SWOOLEC是不错的国产加密&#xff0c;值得推荐官方宣称是永远无法破解的加密算法&#xff0c;针对swoole compiler的代码修复我谈谈我的看法&#xff0c;以小猪o2o生活通&#xff0…

PyTorch 2.2 中文官方教程(十九)

使用 RPC 进行分布式管道并行 原文&#xff1a;pytorch.org/tutorials/intermediate/dist_pipeline_parallel_tutorial.html 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 作者&#xff1a;Shen Li 注意 在github中查看并编辑本教程。 先决条件&#xff1a; PyTorc…

04-Java建造者模式 ( Builder Pattern )

建造者模式 摘要实现范例 建造者模式&#xff08;Builder Pattern&#xff09;使用多个简单的对象一步一步构建成一个复杂的对象 一个Builder 类会一步一步构造最终的对象&#xff0c;该 Builder 类是独立于其他对象的 建造者模式属于创建型模式&#xff0c;它提供了一种创建对…

深度学习手写字符识别:训练模型

说明 本篇博客主要是跟着B站中国计量大学杨老师的视频实战深度学习手写字符识别。 第一个深度学习实例手写字符识别 深度学习环境配置 可以参考下篇博客&#xff0c;网上也有很多教程&#xff0c;很容易搭建好深度学习的环境。 Windows11搭建GPU版本PyTorch环境详细过程 数…

vcruntime140.dll最新的修复方法,一键修复vcruntime140.dll的手段

在这篇文章中&#xff0c;我们将深入探讨并详细介绍各种修复vcruntime140.dll文件缺失或损坏问题的方法。鉴于此类问题广泛存在并影响了众多用户&#xff0c;本文目的是向大家展示不同的修复策略&#xff0c;希望能够帮助每个人解决这些棘手的技术难题。下面一起来看看vcruntim…

【RT-DETR有效改进】UNetv2提出的一种SDI多层次特征融合模块(细节高效涨点)

👑欢迎大家订阅本专栏,一起学习RT-DETR👑 一、本文介绍 本问给大家带来的改进机制是UNetv2提出的一种多层次特征融合模块(SDI)其是一种用于替换Concat操作的模块,SDI模块的主要思想是通过整合编码器生成的层级特征图来增强图像中的语义信息和细节信息。包括皮肤…

黑豹程序员-ElementPlus选择图标器

ElementPlus组件提供了很多图标svg 如何在你的系统中&#xff0c;用户可以使用呢&#xff1f; 这就是图标器&#xff0c;去调用ElementPlus的icon组件库&#xff0c;展示到页面&#xff0c;用户选择&#xff0c;返回选择的组件名称。 效果 代码 <template><el-inpu…

机器学习 - 梯度下降

场景 上一章学习了代价函数&#xff0c;在机器学习中&#xff0c;代价模型是用于衡量模型预测值与真实值之间的差异的函数。它是优化算法的核心&#xff0c;目标是通过调整模型的参数来最小化代价模型的值&#xff0c;从而使模型的预测结果更接近真实值。常见的代价模型是均方…

【Boost】:searcher的建立(四)

searcher的建立 一.初始化二.搜索功能三.完整源代码 sercher主要分为两部分&#xff1a;初始化和查找。 一.初始化 初始化分为两步&#xff1a;1.创建Index对象&#xff1b;2.建立索引 二.搜索功能 搜索分为四个步骤 分词&#xff1b;触发&#xff1a;根据分词找到对应的文档…

架构设计特训

一、考点分布 软件架构风格&#xff08;※※※※&#xff09;层次型软件架构风格&#xff08;※※※※&#xff09;面向服务的软件架构风格&#xff08;※※※※&#xff09;云原生架构风格&#xff08;※※※※&#xff09;质量属性与架构评估&#xff08;※※※※※&#xff…

Transformer实战-系列教程1:Transformer算法解读1

&#x1f6a9;&#x1f6a9;&#x1f6a9;Transformer实战-系列教程总目录 有任何问题欢迎在下面留言 Transformer实战-系列教程1&#xff1a;Transformer算法解读1 Transformer实战-系列教程2&#xff1a;Transformer算法解读2 现在最火的AI内容&#xff0c;chatGPT、视觉大模…