【QT】自制控件---滚动选择器
来源:互联网 发布:webmin nginx 编辑:程序博客网 时间:2024/05/23 01:01
因为我需要有连续的数字以供选择,所以只记了数字范围。如有需求可以改为用任意线性容器保持数据
代码:
self-contained.h
#ifndef SELFCONTAINED_H#define SELFCONTAINED_H#include <QWidget>#include <QMouseEvent>#include <QPainter>#include <QPropertyAnimation>#endif // SELFCONTAINED_H
#ifndef ROLLINGBOX_H#define ROLLINGBOX_H#include "self-contained.h"class RollingBox : public QWidget//GIG_C_GOD{ Q_OBJECT Q_PROPERTY(int deviation READ readDeviation WRITE setDeviation)public: explicit RollingBox(QWidget *parent = 0); void setRange(int min,int max); int readValue();protected: int m_minRange; int m_maxRange; int m_currentValue; bool isDragging; int m_deviation; int m_mouseSrcPos; int m_numSize;//计算所得的数字字符尺寸,以最长的情况为准 QPropertyAnimation *homingAni; void mousePressEvent(QMouseEvent *); void mouseMoveEvent(QMouseEvent *); void mouseReleaseEvent(QMouseEvent *); void paintEvent(QPaintEvent *); void paintNum(QPainter &painter,int num,int deviation); void homing(); int readDeviation(); void setDeviation(int n);signals: void currentValueChanged(int value); void deviationChange(float deviation);public slots:};#endif // ROLLINGBOX_H
rollingbox.cpp
#include "rollingbox.h"RollingBox::RollingBox(QWidget *parent) : QWidget(parent),m_minRange(0),m_maxRange(100), m_currentValue(50),isDragging(0),m_deviation(0),m_numSize(6){ homingAni = new QPropertyAnimation(this,"deviation"); homingAni->setDuration(300); homingAni->setEasingCurve(QEasingCurve::OutQuad);}void RollingBox::setRange(int min,int max){ m_minRange = min; m_maxRange = max; if(m_currentValue < min) m_currentValue = min; if(m_currentValue > max) m_currentValue = max; //计算字符尺寸 m_numSize = 3; int temp = m_maxRange; while(temp > 0) { temp /= 10; m_numSize++; } repaint();}int RollingBox::readValue(){ return m_currentValue;}void RollingBox::mousePressEvent(QMouseEvent *e){ homingAni->stop(); isDragging = 1; m_mouseSrcPos = e->pos().x();}void RollingBox::mouseMoveEvent(QMouseEvent *e){ if(isDragging) { //数值到边界时,阻止继续往对应方向移动 if((m_currentValue == m_minRange && e->pos().x() >= m_mouseSrcPos)|| (m_currentValue == m_maxRange && e->pos().x() <= m_mouseSrcPos)) return; m_deviation = e->pos().x() - m_mouseSrcPos; //若移动速度过快时进行限制 if(m_deviation > (width()-1)/4) m_deviation = (width()-1)/4; else if(m_deviation < -(width()-1)/4) m_deviation = -(width()-1)/4; emit deviationChange((float)m_deviation/((width()-1)/4)); repaint(); }}void RollingBox::mouseReleaseEvent(QMouseEvent *){ if(isDragging) { isDragging = 0; homing(); }}void RollingBox::paintEvent(QPaintEvent *){ QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing, true); int Width = width()-1; int Height = height()-1; if(m_deviation >= Width/4 && m_currentValue > m_minRange) { m_mouseSrcPos += Width/4; m_deviation -= Width/4; m_currentValue -= 1; } if(m_deviation <= -Width/4 && m_currentValue < m_maxRange) { m_mouseSrcPos -= Width/4; m_deviation += Width/4; m_currentValue += 1; } //中间数字 paintNum(painter,m_currentValue,m_deviation); //两侧数字1 if(m_currentValue != m_minRange) paintNum(painter,m_currentValue-1,m_deviation-Width/4); if(m_currentValue != m_maxRange) paintNum(painter,m_currentValue+1,m_deviation+Width/4); //两侧数字2,超出则不显示 if(m_deviation >= 0 && m_currentValue-2 >= m_minRange) paintNum(painter,m_currentValue-2,m_deviation-Width/2); if(m_deviation <= 0 && m_currentValue+2 <= m_maxRange) paintNum(painter,m_currentValue+2,m_deviation+Width/2); //边框 painter.setPen(QPen(QColor(0,0,0,120),2)); painter.drawLine(Width/8*3,0,Width/8*3,Height); painter.drawLine(Width/8*5,0,Width/8*5,Height);}void RollingBox::paintNum(QPainter &painter,int num,int deviation){ int Width = width()-1; int Height = height()-1; int size = (Width - qAbs(deviation))/m_numSize; int transparency = 255-510*qAbs(deviation)/Width; int width = Width/2-3*qAbs(deviation)/4; int x = Width/2+deviation-width/2; QFont font; font.setPixelSize(size); painter.setFont(font); painter.setPen(QColor(0,0,0,transparency)); painter.drawText(QRectF(x,0,width,Height), Qt::AlignCenter, QString::number(num));}void RollingBox::homing(){ //将数字矫正到中心 if(m_deviation > width()/8) { homingAni->setStartValue((width()-1)/8-m_deviation); homingAni->setEndValue(0); m_currentValue--; } else if(m_deviation > -width()/8) { homingAni->setStartValue(m_deviation); homingAni->setEndValue(0); } else if(m_deviation < -width()/8) { homingAni->setStartValue(-(width()-1)/8-m_deviation); homingAni->setEndValue(0); m_currentValue++; } emit currentValueChanged(m_currentValue); homingAni->start();}int RollingBox::readDeviation(){ return m_deviation;}void RollingBox::setDeviation(int n){ m_deviation = n; repaint();}
1 1
- 【QT】自制控件---滚动选择器
- 自制Qt IP编辑控件
- 自制控件
- 自制CSS颜色选择器
- 滚动选择器
- 自制滚动条
- 自制滚动条
- Android自定义控件实战——滚动选择器PickerView
- Android自定义控件实战——滚动选择器PickerView
- Android自定义控件实战——滚动选择器PickerView
- Android自定义控件实战——滚动选择器PickerView
- Android自定义控件实战——滚动选择器PickerView
- Android自定义控件实战——滚动选择器PickerView
- Android自定义控件实战——滚动选择器PickerView
- Android自定义控件实战——滚动选择器PickerView
- Android自定义控件实战—滚动选择器PickerView
- Android自定义控件实战——滚动选择器PickerView
- 开源控件滚动选择器WheelView学习笔记 & 省市区联动选择器
- python基础-numpy.bincount详解
- 【Java基础】——int与Integer区别快来瞅瞅
- 古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?
- JAVA类加载器理解
- iOS Runloop学习
- 【QT】自制控件---滚动选择器
- 开通博客
- Python--变量类型
- 垃圾回收和内存分配策略(二)
- DigitRecognizer
- 4.vc从零开始 -- Win32项目hello world(二)
- java线程安全的类
- cocoapods的安装 遇到 Error installing pods:activesupport requires Ruby version >=2.2.2
- 矩阵快速幂模板