【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


rollingbox.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
原创粉丝点击