#pragma execution_character_set("utf-8")
#include "tumbler.h"
#include "qpainter.h"
#include "qevent.h"
#include "qdebug.h"
Tumbler::Tumbler(QWidget *parent) : QWidget(parent)
{
currentIndex = 0;
currentValue = "1";
for (int i = 1; i <= 12; i++) {
listValue.append(QString::number(i));
}
foreground = QColor(140, 140, 140);
background = QColor(40, 40, 40, 0);
lineColor = QColor(46, 142, 180, 200);
textColor = QColor(255, 255, 255);
horizontal = false;
percent = 3;
offset = 0;
pressed = 0;
pressedPos = 0;
currentPos = 0;
setFont(QFont("Arial", 8));
}
void Tumbler::wheelEvent(QWheelEvent *e)
{
//滚动的角度,*8就是鼠标滚动的距离
int degrees = e->delta() / 8;
//滚动的步数,*15就是鼠标滚动的角度
int steps = degrees / 15;
//如果是正数代表为左边移动,负数代表为右边移动
if (e->orientation() == Qt::Vertical) {
int index = currentIndex - steps;
if (steps > 0) {
if (index > 0) {
setCurrentIndex(index);
} else {
setCurrentIndex(0);
}
} else {
if (index < listValue.count() - 1) {
setCurrentIndex(index);
} else {
setCurrentIndex(listValue.count() - 1);
}
}
}
}
void Tumbler::mousePressEvent(QMouseEvent *e)
{
pressed = true;
int target = e->pos().x();
if (!horizontal) {
target = e->pos().y();
}
pressedPos = target;
}
void Tumbler::mouseMoveEvent(QMouseEvent *e)
{
int count = listValue.count();
if (count <= 1) {
return;
}
int pos = e->pos().x();
int target = this->width();
if (!horizontal) {
pos = e->pos().y();
target = this->height();
}
int index = listValue.indexOf(currentValue);
if (pressed) {
//数值到边界时,阻止继续往对应方向移动
if ((index == 0 && pos >= pressedPos) || (index == count - 1 && pos <= pressedPos)) {
return;
}
offset = pos - pressedPos;
//若移动速度过快时进行限制
if (offset > target / percent) {
offset = target / percent;
} else if (offset < -target / percent) {
offset = -target / percent;
}
static int oldIndex = -1;
if (oldIndex != index) {
emit currentIndexChanged(index);
emit currentValueChanged(listValue.at(index));
oldIndex = index;
}
update();
}
}
void Tumbler::mouseReleaseEvent(QMouseEvent *)
{
if (pressed) {
pressed = false;
//矫正到居中位置
checkPosition();
}
}
void Tumbler::paintEvent(QPaintEvent *)
{
//绘制准备工作,启用反锯齿
QPainter painter(this);
painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
int count = listValue.count();
if (count <= 1) {
return;
}
int target = this->width();
if (!horizontal) {
target = this->height();
}
int index = listValue.indexOf(currentValue);
//当右移偏移量大于比例且当前值不是第一个则索引-1
if (offset >= target / percent && index > 0) {
pressedPos += target / percent;
offset -= target / percent;
index -= 1;
}
//当左移偏移量小于比例且当前值不是末一个则索引+1
if (offset <= -target / percent && index < count - 1) {
pressedPos -= target / percent;
offset += target / percent;
index += 1;
}
currentIndex = index;
currentValue = listValue.at(index);
//绘制背景
drawBg(&painter);
//绘制线条
drawLine(&painter);
//绘制中间值
painter.setPen(textColor);
drawText(&painter, index, offset);
painter.setPen(foreground);
//绘制左侧值
if (index != 0) {
drawText(&painter, index - 1, offset - target / percent);
}
//绘制右侧值
if (index != count - 1) {
drawText(&painter, index + 1, offset + target / percent);
}
}
void Tumbler::drawBg(QPainter *painter)
{
painter->save();
painter->setPen(Qt::NoPen);
painter->setBrush(background);
painter->drawRect(rect());
painter->restore();
}
void Tumbler::drawLine(QPainter *painter)
{
//上下部分偏移量
int offset = 10;
int width = this->width();
int height = this->height();
painter->save();
painter->setBrush(Qt::NoBrush);
QPen pen;
pen.setWidth(3);
pen.setColor(lineColor);
pen.setCapStyle(Qt::RoundCap);
painter->setPen(pen);
//每次同时存在三个元素
if (horizontal) {
painter->drawLine(width / 3 * 1, offset, width / 3 * 1, height - offset);
painter->drawLine(width / 3 * 2, offset, width / 3 * 2, height - offset);
} else {
painter->drawLine(offset, height / 3 * 1, width - offset, height / 3 * 1);
painter->drawLine(offset, height / 3 * 2, width - offset, height / 3 * 2);
}
painter->restore();
}
void Tumbler::drawText(QPainter *painter, int index, int offset)
{
painter->save();
int width = this->width();
int height = this->height();
QString strValue = listValue.at(index);
int target = width;
if (!horizontal) {
target = height;
}
QFont font = painter->font();
font.setPixelSize((target - qAbs(offset)) / 8);
painter->setFont(font);
if (horizontal) {
int textWidth = painter->fontMetrics().width(strValue);
int initX = width / 2 + offset - textWidth / 2;
painter->drawText(QRect(initX, 0, textWidth, height), Qt::AlignCenter, strValue);
//计算最后中间值停留的起始坐标,以便鼠标松开时矫正居中
if (index == currentIndex) {
currentPos = initX;
}
} else {
int textHeight = painter->fontMetrics().height();
int initY = height / 2 + offset - textHeight / 2;
painter->drawText(QRect(0, initY, width, textHeight), Qt::AlignCenter, strValue);
//计算最后中间值停留的起始坐标,以便鼠标松开时矫正居中
if (index == currentIndex) {
currentPos = initY;
}
}
painter->restore();
}
void Tumbler::checkPosition()
{
int target = this->width();
if (!horizontal) {
target = this->height();
}
//左右滑动样式,往左滑动时,offset为负数,当前值所在X轴坐标小于宽度的一半,则将当前值设置为下一个值
//左右滑动样式,往右滑动时,offset为正数,当前值所在X轴坐标大于宽度的一半,则将当前值设置为上一个值
//上下滑动样式,往上滑动时,offset为负数,当前值所在Y轴坐标小于高度的一半,则将当前值设置为下一个值
//上下滑动样式,往下滑动时,offset为正数,当前值所在Y轴坐标大于高度的一半,则将当前值设置为上一个值
if (offset < 0) {
if (currentPos < target / 2) {
offset = 0;
setCurrentIndex(currentIndex + 1);
}
} else {
if (currentPos > target / 2) {
offset = 0;
setCurrentIndex(currentIndex - 1);
}
}
}
QStringList Tumbler::getListValue() const
{
return this->listValue;
}
int Tumbler::getCurrentIndex() const
{
return this->currentIndex;
}
QString Tumbler::getCurrentValue() const
{
return this->currentValue;
}
bool Tumbler::getHorizontal() const
{
return this->horizontal;
}
QColor Tumbler::getForeground() const
{
return this->
没有合适的资源?快使用搜索试试~ 我知道了~
SliderTime.7z
![preview](https://csdnimg.cn/release/downloadcmsfe/public/img/white-bg.ca8570fa.png)
共12个文件
cpp:4个
h:3个
d332de5:1个
![preview-icon](https://csdnimg.cn/release/downloadcmsfe/public/img/scale.ab9e0183.png)
1.该资源内容由用户上传,如若侵权请联系客服进行举报
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
2.虚拟产品一经售出概不退款(资源遇到问题,请及时私信上传者)
版权申诉
0 下载量 135 浏览量
2022-04-12
21:58:51
上传
评论
收藏 8KB 7Z 举报
温馨提示
SliderTime.7z
资源详情
资源评论
资源推荐
收起资源包目录
![package](https://csdnimg.cn/release/downloadcmsfe/public/img/package.f3fc750b.png)
![folder](https://csdnimg.cn/release/downloadcmsfe/public/img/folder.005fa2e5.png)
![file-type](https://csdnimg.cn/release/download/static_files/pc/images/minetype/UNKNOWN.png)
![file-type](https://csdnimg.cn/release/download/static_files/pc/images/minetype/UNKNOWN.png)
![file-type](https://csdnimg.cn/release/download/static_files/pc/images/minetype/UNKNOWN.png)
![file-type](https://csdnimg.cn/release/download/static_files/pc/images/minetype/UNKNOWN.png)
![file-type](https://csdnimg.cn/release/download/static_files/pc/images/minetype/UNKNOWN.png)
![file-type](https://csdnimg.cn/release/download/static_files/pc/images/minetype/UNKNOWN.png)
![file-type](https://csdnimg.cn/release/download/static_files/pc/images/minetype/UNKNOWN.png)
![file-type](https://csdnimg.cn/release/download/static_files/pc/images/minetype/UNKNOWN.png)
![file-type](https://csdnimg.cn/release/download/static_files/pc/images/minetype/UNKNOWN.png)
![file-type](https://csdnimg.cn/release/download/static_files/pc/images/minetype/UNKNOWN.png)
![file-type](https://csdnimg.cn/release/download/static_files/pc/images/minetype/UNKNOWN.png)
![file-type](https://csdnimg.cn/release/download/static_files/pc/images/minetype/UNKNOWN.png)
共 12 条
- 1
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![txt](https://img-home.csdnimg.cn/images/20210720083642.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![7z](https://img-home.csdnimg.cn/images/20210720083312.png)
![gz](https://img-home.csdnimg.cn/images/20210720083447.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![pdf](https://img-home.csdnimg.cn/images/20210720083512.png)
![exe](https://img-home.csdnimg.cn/images/20210720083343.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![rar](https://img-home.csdnimg.cn/images/20210720083606.png)
![zip](https://img-home.csdnimg.cn/images/20210720083736.png)
![avatar](https://profile-avatar.csdnimg.cn/11124d2ce5db41368adec8b1ad4e99f7_xxzhaoming.jpg!1)
![avatar-vip](https://csdnimg.cn/release/downloadcmsfe/public/img/user-vip.1c89f3c5.png)
应用市场
- 粉丝: 658
- 资源: 3866
上传资源 快速赚钱
我的内容管理 展开
我的资源 快来上传第一个资源
我的收益
登录查看自己的收益我的积分 登录查看自己的积分
我的C币 登录后查看C币余额
我的收藏
我的下载
下载帮助
![voice](https://csdnimg.cn/release/downloadcmsfe/public/img/voice.245cc511.png)
![center-task](https://csdnimg.cn/release/downloadcmsfe/public/img/center-task.c2eda91a.png)
安全验证
文档复制为VIP权益,开通VIP直接复制
![dialog-icon](https://csdnimg.cn/release/downloadcmsfe/public/img/green-success.6a4acb44.png)
评论0