Qt5 双滑块支持float变化的控件,以及单滑块float控件,供大家参考

来源:互联网 发布:世界最流行的编程语言 编辑:程序博客网 时间:2024/05/16 04:57
最近做到一个项目,需要设置一个参数的上下限,最开始考虑的办法是用QSlider控件来实现,发现有两个不太合适的地方。
  • 一个参数需要用两个控件来设置,而且两者之间还有大小关系的限制,比较麻烦;
  • QSlider只支持int类型的输入与改变。
因此,决定自己写一个,本着资源共享的精神,特将代码贴出,供大家参考,如有更好的想法,也欢迎指正与交流。

双滑块的代码

#ifndef DOUBLESLIDER_H#define DOUBLESLIDER_H#include class DoubleSlider : public QWidget{    Q_OBJECTpublic:    DoubleSlider(QWidget* parent = 0);    void setRange(float min, float max);    void setSingleStep(float step);    enum State{ MinHandle,MaxHandle,None};    float minValue() const;    float maxValue() const;    float minRange() const;    float maxRange() const;public slots:    void setLabel(const QString& label);    void setMaxValue(float val);    void setMinValue(float val);signals:    void minValueChanged(float);    void maxValueChanged(float);private:    float m_min;    float m_max;    float m_singleStep;    float m_minValue;    float m_maxValue;    QRect minHandleRegion;    QRect maxHandleRegion;    State m_state;    QString m_label;protected:    void paintEvent(QPaintEvent* event);    void paintColoredRect(QRect rect, QColor color, QPainter* painter);    void paintValueLabel(QPainter* painter);    void mousePressEvent(QMouseEvent* event);    void mouseMoveEvent(QMouseEvent* event);    void keyPressEvent(QKeyEvent *event);    void leaveEvent(QEvent* event);};#endif // DOUBLESLIDER_H#include "doubleslider.h"#include #include DoubleSlider::DoubleSlider(QWidget* parent)    : QWidget(parent)    , m_min(0.0f)    , m_max(99.0f)    , m_singleStep(0.1f)    , m_minValue(0.0f)    , m_maxValue(99.0f)    , m_state(None){    setFixedHeight(50);    setFocusPolicy(Qt::StrongFocus);}void DoubleSlider::paintEvent(QPaintEvent* event){    QWidget::paintEvent(event);    QPainter painter(this);    paintValueLabel(&painter);}void DoubleSlider::paintColoredRect(QRect rect, QColor color ,QPainter* painter){    painter->fillRect(rect,QBrush(color));}void DoubleSlider::paintValueLabel(QPainter* painter){    painter->setBrush(Qt::NoBrush);    painter->setPen(Qt::black);    painter->setFont(QFont("Arial",12));    QString minValueString = QString::number(m_minValue,'f',3);    QString maxValueString = QString::number(m_maxValue,'f',3);    QFontMetrics metrics = painter->fontMetrics();    int mintextWidth = metrics.width(minValueString);    int maxtextWidth = metrics.width(maxValueString);    int textHeight = metrics.height();    //---- paint text    painter->drawText(QRectF(2,4,mintextWidth,textHeight),minValueString);    painter->drawText(QRectF(width() - maxtextWidth -2, 4, maxtextWidth,textHeight), maxValueString);    //----- paint label    painter->setFont(QFont("Arial",12));    metrics = painter->fontMetrics();    int labelWidth = metrics.width(m_label);    int labelHeight = metrics.height();    QRectF textRect = QRectF((width()/2 - labelWidth/2), 0,labelWidth,labelHeight);    painter->drawText(textRect,m_label);    int minPos = ( m_minValue - m_min ) * width() / (m_max - m_min);    int maxPos = (m_maxValue - m_min ) * width() /  (m_max - m_min);    if(minPos <= 4){        minPos = 4;    }else if(minPos >= width() - 8){        minPos = width() - 8;    }else{}    if(maxPos <= 4){        maxPos = 4;    }else if(maxPos >= width() -8){        maxPos = width() - 8;    }else{}    //----- paint groove    paintColoredRect(QRect(4,37,width() - 8,2),Qt::gray,painter);    paintColoredRect(QRect(minPos + 4,37,maxPos - minPos,2),QColor(51,153,155),painter);    //----- handle    minHandleRegion = QRect(minPos ,30,8,16);    maxHandleRegion = QRect(maxPos ,30,8,16);    //-----paint Handle    QColor minColor  = (m_state == MinHandle) ? QColor(51,153,155) : Qt::darkGray;    QColor maxColor  = (m_state == MaxHandle) ? QColor(51,153,155) : Qt::darkGray;    paintColoredRect(minHandleRegion,minColor,painter);    paintColoredRect(maxHandleRegion,maxColor,painter);}inline float getValidValue(float val, float min, float max){    float tmp = std::max(val, min);    return std::min(tmp, max);}void DoubleSlider::setRange(float min, float max){    m_min = min;    m_max = max;    if(minValue() < m_min)        setMinValue(m_min);    if(maxValue() > m_max){        setMaxValue(m_max);    }}void DoubleSlider::setSingleStep(float step){    m_singleStep = step;}float DoubleSlider::minValue() const{    return m_minValue;}void DoubleSlider::setMinValue(float val){    if(fabs( m_minValue - val ) > 0.0001 ){        m_minValue = val;        emit minValueChanged(val);    }}float DoubleSlider::maxValue() const{    return m_maxValue;}void DoubleSlider::setMaxValue(float val){    if(fabs(m_maxValue - val) > 0.0001){        m_maxValue = val;        emit maxValueChanged(val);    }}void DoubleSlider::setLabel(const QString& label){   m_label = label;   update();}void DoubleSlider::leaveEvent(QEvent* event){    QWidget::leaveEvent(event);    m_state = None;    update();}float DoubleSlider::minRange() const{    return m_min;}float DoubleSlider::maxRange() const{    return m_max;}void DoubleSlider::mousePressEvent(QMouseEvent* event){    if(minHandleRegion.contains(event->pos())){        m_state = MinHandle;    }else if(maxHandleRegion.contains(event->pos())){        m_state = MaxHandle;    }else{        m_state = None;    }    if(fabs(minValue() - maxValue()) < 0.001){        if(fabs(minValue() - m_min) < 0.001){            m_state = MaxHandle;        }else if(fabs(minValue() - m_max) < 0.001){            m_state = MinHandle;        }else{}    }    update();}void DoubleSlider::mouseMoveEvent(QMouseEvent* event){    if(event->buttons() & Qt::LeftButton){        float move = event->x() * (m_max - m_min) * 1.0/ width() + m_min;        switch(m_state){            case MinHandle:{                float val = getValidValue( move, m_min,maxValue());                setMinValue(val);                break;            }            case MaxHandle:{                    float val = getValidValue(move, minValue(), m_max);                    setMaxValue(val);                    break;            }            case None:default: break;        }    }    update();}void DoubleSlider::keyPressEvent(QKeyEvent *event){    QWidget::keyPressEvent(event);    if(event->key() == Qt::Key_Left){        if(m_state == MinHandle){            float val = getValidValue(minValue()- m_singleStep, m_min ,maxValue());            setMinValue(val);        }else if(m_state == MaxHandle) {            float val = getValidValue(maxValue()- m_singleStep, minValue() ,m_max);            setMaxValue(val);        }else{}    }else if(event->key() == Qt::Key_Right){        if(m_state == MinHandle){            float val = getValidValue(minValue() + m_singleStep, m_min ,maxValue());            setMinValue(val);        }else if(m_state == MaxHandle) {            float val = getValidValue(maxValue() + m_singleStep, minValue() ,m_max);            setMaxValue(val);        }else{}    }    update();}




原创粉丝点击