#include "DoubleHandleSlider.h"
#include <QLabel>
#include <QVBoxLayout>
#include <QPainter>
#include <QPainterPath>
#include <QMouseEvent>
#include <QEnterEvent>
#include <QEvent>
DoubleHandleSlider::DoubleHandleSlider(int minVal, int maxVal, QWidget *parent) : QWidget(parent)
{
m_minVal = minVal;
m_maxVal = maxVal;
m_duration = maxVal- m_minVal;
setFixedHeight(50);
m_leftHadle = new QLabel(this);
m_leftHadle->setObjectName("SliderHandle");
m_leftHadle->setFixedSize(7, 15);
m_leftHadle->installEventFilter(this);
m_rightHandle = new QLabel(this);
m_rightHandle->setObjectName("SliderHandle");
m_rightHandle->setFixedSize(7, 15);
m_rightHandle->installEventFilter(this);
m_leftValTipsLab = new QLabel(this);
m_leftValTipsLab->setObjectName("SliderValTips");
m_leftValTipsLab->setMinimumWidth(50);
m_rightValTipsLab = new QLabel(this);
m_rightValTipsLab->setObjectName("SliderValTips");
m_rightValTipsLab->setMinimumWidth(50);
m_leftVal = minVal;
m_rightVal = maxVal;
setMouseTracking(true);
}
void DoubleHandleSlider::setLeftRightVal(int leftVal, int rightVal)
{
m_leftVal = leftVal;
m_rightVal = rightVal;
}
void DoubleHandleSlider::setHandleIntervalValue(int val)
{
m_handleIntervalVal = val;
}
void DoubleHandleSlider::refreshPosition(const float &leftX, const float &rightX)
{
m_leftHadle->move(leftX, 22);
m_rightHandle->move(rightX, 22);
int leftTipsTextWidth = m_leftValTipsLab->fontMetrics().boundingRect(QString::number(m_leftVal)).width();
int leftTipsX = leftX- leftTipsTextWidth/2 +2;
int rightTipsTextWidht = m_rightValTipsLab->fontMetrics().boundingRect(QString::number(m_rightVal)).width();
int rightTipsX = rightX- rightTipsTextWidht/2 +2;
int rightTipXLimit = m_sliderWidth- rightTipsTextWidht- 2;
if(leftTipsX< 0)
leftTipsX = 0;
else if(leftTipsX> rightTipXLimit)
leftTipsX = rightTipXLimit;
m_leftValTipsLab->move(leftTipsX, 0);
if(rightTipsX> rightTipXLimit)
rightTipsX = rightTipXLimit;
else if(rightTipsX< 0)
rightTipsX = 0;
m_rightValTipsLab->move(rightTipsX, 0);
m_leftValTipsLab->setText(QString::number(m_leftVal));
m_rightValTipsLab->setText(QString::number(m_rightVal));
}
void DoubleHandleSlider::refreshLeftVal(float x)
{
//重新计算左值;
m_leftVal = m_duration* x/m_sliderWidth+ m_minVal;
// qDebug()<< m_leftVal;
if(m_leftVal< m_minVal)
m_leftVal = m_minVal;
else if(m_leftVal>= m_rightVal- m_handleIntervalVal)
m_leftVal = m_rightVal- m_handleIntervalVal;
emit valueChanged(m_leftVal, m_rightVal);
}
void DoubleHandleSlider::refreshRightVal(float x)
{
//重新计算右值;
m_rightVal = m_duration* x/m_sliderWidth+ m_minVal;
// qDebug()<< m_rightVal;
if(m_rightVal> m_maxVal)
m_rightVal = m_maxVal;
else if(m_rightVal<= m_leftVal+ m_handleIntervalVal)
m_rightVal = m_leftVal+ m_handleIntervalVal;
emit valueChanged(m_leftVal, m_rightVal);
}
void DoubleHandleSlider::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
m_sliderWidth = width()- m_rightHandle->width();
//创建painter;
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing, true);
//创建pen,pen的作用时描边,因为这里的样式是没有边的,所以需要把pen的类型设为NoPen;
QPen pen;
pen.setStyle(Qt::PenStyle::NoPen);
painter.setPen(pen);
//创建画刷,滑槽是通过画刷绘制的,所以这里要设定好滑槽的颜色;
QBrush brush(QColor(0x7D, 0x7D, 0x7D));
painter.setBrush(brush);
//创建painter 想要绘制的路径,之所以要用这个方法,是因为我们需要画出两端是圆弧形的滑槽;最后两个参数控制了两端圆弧的实现;
QPainterPath painterPath;
painterPath.addRoundedRect(0, 28, m_sliderWidth, 3, 3, 3);
//绘制手柄的两边灰色滑动条;
painter.drawPath(painterPath);
//画刷更换颜色,继续画另一个滑槽;
brush.setColor(QColor(0xFF, 0x55, 0x57));
painter.setBrush(brush);
//计算left handle和right handle的位置,同时也是另一个滑槽的两端位置;
float leftX = m_sliderWidth* (float)(m_leftVal-m_minVal)/m_duration;
float rightX = m_sliderWidth* (float)(m_rightVal-m_minVal)/m_duration;
QPainterPath painterPath2;
painterPath2.addRoundedRect(leftX, 28, rightX- leftX, 3, 3, 3);
//绘制两手柄中间亮色滑动条;
painter.drawPath(painterPath2);
//刷新handle和tips的位置;
refreshPosition(leftX, rightX);
}
void DoubleHandleSlider::mouseMoveEvent(QMouseEvent *event)
{
if(m_mouseEnterType == NotInHandle)
{
//判断鼠标是否在滑动条范围内;
if(event->pos().y()< m_leftHadle->y() || event->pos().y()> m_leftHadle->y()+ m_leftHadle->height())
{
setCursor(QCursor(Qt::ArrowCursor));
}
else
{
setCursor(QCursor(Qt::PointingHandCursor));
}
}
else if(m_mouseEnterType == InLeftHandle)
{
refreshLeftVal(event->pos().x());
update();
}
else if(m_mouseEnterType == InRightHandle)
{
refreshRightVal(event->pos().x());
update();
}
}
bool DoubleHandleSlider::eventFilter(QObject *watched, QEvent *event)
{
if(watched == m_leftHadle)
{
if(event->type() == QEvent::Enter)
{
setCursor(QCursor(Qt::OpenHandCursor));
m_mouseEnterType = InLeftHandle;
}
else if(event->type() == QEvent::Leave)
{
setCursor(QCursor(Qt::OpenHandCursor));
m_mouseEnterType = NotInHandle;
}
}
else if(watched == m_rightHandle)
{
if(event->type() == QEvent::Enter)
{
setCursor(QCursor(Qt::OpenHandCursor));
m_mouseEnterType = InRightHandle;
}
else if(event->type() == QEvent::Leave)
{
setCursor(QCursor(Qt::OpenHandCursor));
m_mouseEnterType = NotInHandle;
}
}
else
{
return QWidget::eventFilter(watched, event);
}
return false;
}
void DoubleHandleSlider::mousePressEvent(QMouseEvent *event)
{
//判断鼠标是否在滑动条范围内;
if(event->pos().y()< m_leftHadle->y() || event->pos().y()> m_leftHadle->y()+ m_leftHadle->height())
return;
if(m_mouseEnterType == NotInHandle)
{
int handleDuration = m_rightHandle->x()- m_leftHadle->x();
//鼠标在左手柄的左边;
if(event->pos().x()< m_leftHadle->x())
refreshLeftVal(event->pos().x());
//鼠标在右手柄的右边;
else if(event->pos().x()> m_rightHandle->x())
refreshRightVal(event->pos().x());
//鼠标在两个手柄的中间,但靠近左手柄;
else if(event->pos().x()< m_leftHadle->pos().x()+ handleDuration/2)
refreshLeftVal(event->pos().x());
//鼠标在两个手柄的中间,但更靠近有手柄;
else if(event->pos().x()>= m_leftHadle->pos().x()+ handleDuration/2)
refreshRightVal(event->pos().x());
update();
}
else if(m_mouseEnterType == InLeftHandle)
{
setCursor(QCursor(Qt::ClosedHandCursor));
}
else if(m_mouseEnterType == InRightHandle)
{
setCursor(QCursor(Qt::ClosedHandCursor));
}
}
没有合适的资源?快使用搜索试试~ 我知道了~
Qt 实现双控制柄的Slider
共9个文件
cpp:3个
h:2个
ui:1个
10 下载量 74 浏览量
2023-07-23
18:21:42
上传
评论
收藏 6KB ZIP 举报
温馨提示
关联博客:https://blog.csdn.net/JellyLi2091/article/details/131882488?spm=1001.2014.3001.5502 1.实现带有左右两个控制柄的滑动条; 2.控件可设定最小值和最大值; 3.控件可设定控制柄的最小距离;
资源推荐
资源详情
资源评论
收起资源包目录
DoubleHandleSlider.zip (9个子文件)
DoubleHandleSlider
MainWidget.ui 410B
MainWidget.h 447B
MainWidget.cpp 614B
DoubleHandleSlider.pro 703B
qss.qrc 98B
DoubleHandleSlider.cpp 8KB
main.cpp 183B
qss
normal.qss 411B
DoubleHandleSlider.h 2KB
共 9 条
- 1
资源评论
乘风-
- 粉丝: 19
- 资源: 13
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 计算机视觉课程设计-基于Chinese-CLIP的图文检索系统Python实现源码+文档说明
- 计算机视觉Python课程设计-基于Chinese-CLIP的图文检索系统源码+文档说明
- 基于网络分析与元胞自动机构建难民迁移模型及其政策建议
- 欧洲难民危机下基于动态网络规划模型与系统动力学的优化难民迁移策略
- 基于时间约束函数的埃及水资源稀缺度模型与干预提案
- 全球水资源短缺与海地水危机的多学科分析和干预计划研究
- 印度水资源预测与干预政策分析:基于多元线性回归模型的技术研究与应用
- 微信小程序点餐系统微信小程序开发实战项目源码+数据库+详细文档说明(高分项目)
- Flutter jar包
- 基于微信平台的点餐系统小程序完整源码+文档说明+数据库(高分毕业设计项目)
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功