• Qt DoubleSlider 双滑块支持float变化的控件,以及单滑块float控件


    最近做到一个项目,需要设置一个参数的上下限,最开始考虑的办法是用QSlider控件来实现,发现有两个不太合适的地方。

    • 一个参数需要用两个控件来设置,而且两者之间还有大小关系的限制,比较麻烦;
    • QSlider只支持int类型的输入与改变。

    因此,决定自己写一个,本着资源共享的精神,特将代码贴出,供大家参考,如有更好的想法,也欢迎指正与交流。

    双滑块的代码

     1 #ifndef DOUBLESLIDER_H
     2 #define DOUBLESLIDER_H
     3  
     4 #include 
     5  
     6 class DoubleSlider : public QWidget
     7 {
     8     Q_OBJECT
     9 public:
    10     DoubleSlider(QWidget* parent = 0);
    11     void setRange(float min, float max);
    12     void setSingleStep(float step);
    13  
    14     enum State{ MinHandle,MaxHandle,None};
    15  
    16     float minValue() const;
    17     float maxValue() const;
    18  
    19     float minRange() const;
    20     float maxRange() const;
    21  
    22 public slots:
    23     void setLabel(const QString& label);
    24     void setMaxValue(float val);
    25     void setMinValue(float val);
    26  
    27 signals:
    28     void minValueChanged(float);
    29     void maxValueChanged(float);
    30  
    31 private:
    32     float m_min;
    33     float m_max;
    34     float m_singleStep;
    35  
    36     float m_minValue;
    37     float m_maxValue;
    38  
    39     QRect minHandleRegion;
    40     QRect maxHandleRegion;
    41  
    42     State m_state;
    43  
    44     QString m_label;
    45  
    46 protected:
    47     void paintEvent(QPaintEvent* event);
    48     void paintColoredRect(QRect rect, QColor color, QPainter* painter);
    49     void paintValueLabel(QPainter* painter);
    50  
    51     void mousePressEvent(QMouseEvent* event);
    52     void mouseMoveEvent(QMouseEvent* event);
    53  
    54     void keyPressEvent(QKeyEvent *event);
    55     void leaveEvent(QEvent* event);
    56  
    57 };
    58  
    59 #endif // DOUBLESLIDER_H
      1 #include "doubleslider.h"
      2 #include 
      3 #include 
      4  
      5 DoubleSlider::DoubleSlider(QWidget* parent)
      6     : QWidget(parent)
      7     , m_min(0.0f)
      8     , m_max(99.0f)
      9     , m_singleStep(0.1f)
     10     , m_minValue(0.0f)
     11     , m_maxValue(99.0f)
     12     , m_state(None)
     13 {
     14     setFixedHeight(50);
     15     setFocusPolicy(Qt::StrongFocus);
     16 }
     17  
     18 void DoubleSlider::paintEvent(QPaintEvent* event)
     19 {
     20     QWidget::paintEvent(event);
     21     QPainter painter(this);
     22     paintValueLabel(&painter);
     23 }
     24  
     25 void DoubleSlider::paintColoredRect(QRect rect, QColor color ,QPainter* painter)
     26 {
     27     painter->fillRect(rect,QBrush(color));
     28 }
     29  
     30 void DoubleSlider::paintValueLabel(QPainter* painter)
     31 {
     32     painter->setBrush(Qt::NoBrush);
     33     painter->setPen(Qt::black);
     34     painter->setFont(QFont("Arial",12));
     35  
     36     QString minValueString = QString::number(m_minValue,'f',3);
     37     QString maxValueString = QString::number(m_maxValue,'f',3);
     38  
     39     QFontMetrics metrics = painter->fontMetrics();
     40     int mintextWidth = metrics.width(minValueString);
     41     int maxtextWidth = metrics.width(maxValueString);
     42     int textHeight = metrics.height();
     43  
     44     //---- paint text
     45     painter->drawText(QRectF(2,4,mintextWidth,textHeight),minValueString);
     46     painter->drawText(QRectF(width() - maxtextWidth -2, 4, maxtextWidth,textHeight), maxValueString);
     47  
     48  
     49     //----- paint label
     50     painter->setFont(QFont("Arial",12));
     51     metrics = painter->fontMetrics();
     52     int labelWidth = metrics.width(m_label);
     53     int labelHeight = metrics.height();
     54  
     55     QRectF textRect = QRectF((width()/2 - labelWidth/2), 0,labelWidth,labelHeight);
     56  
     57     painter->drawText(textRect,m_label);
     58  
     59  
     60     int minPos = ( m_minValue - m_min ) * width() / (m_max - m_min);
     61     int maxPos = (m_maxValue - m_min ) * width() /  (m_max - m_min);
     62  
     63     if(minPos <= 4){
     64         minPos = 4;
     65     }else if(minPos >= width() - 8){
     66         minPos = width() - 8;
     67     }else{}
     68  
     69     if(maxPos <= 4){
     70         maxPos = 4;
     71     }else if(maxPos >= width() -8){
     72         maxPos = width() - 8;
     73     }else{}
     74  
     75  
     76     //----- paint groove
     77     paintColoredRect(QRect(4,37,width() - 8,2),Qt::gray,painter);
     78     paintColoredRect(QRect(minPos + 4,37,maxPos - minPos,2),QColor(51,153,155),painter);
     79  
     80     //----- handle
     81  
     82     minHandleRegion = QRect(minPos ,30,8,16);
     83     maxHandleRegion = QRect(maxPos ,30,8,16);
     84  
     85     //-----paint Handle
     86     QColor minColor  = (m_state == MinHandle) ? QColor(51,153,155) : Qt::darkGray;
     87     QColor maxColor  = (m_state == MaxHandle) ? QColor(51,153,155) : Qt::darkGray;
     88     paintColoredRect(minHandleRegion,minColor,painter);
     89     paintColoredRect(maxHandleRegion,maxColor,painter);
     90 }
     91  
     92 inline float getValidValue(float val, float min, float max)
     93 {
     94     float tmp = std::max(val, min);
     95     return std::min(tmp, max);
     96 }
     97  
     98  
     99 void DoubleSlider::setRange(float min, float max)
    100 {
    101     m_min = min;
    102     m_max = max;
    103  
    104     if(minValue() < m_min)
    105         setMinValue(m_min);
    106  
    107     if(maxValue() > m_max){
    108         setMaxValue(m_max);
    109     }
    110 }
    111  
    112 void DoubleSlider::setSingleStep(float step)
    113 {
    114     m_singleStep = step;
    115 }
    116  
    117 float DoubleSlider::minValue() const
    118 {
    119     return m_minValue;
    120 }
    121 void DoubleSlider::setMinValue(float val)
    122 {
    123     if(fabs( m_minValue - val ) > 0.0001 ){
    124         m_minValue = val;
    125         emit minValueChanged(val);
    126     }
    127 }
    128  
    129 float DoubleSlider::maxValue() const
    130 {
    131     return m_maxValue;
    132 }
    133 void DoubleSlider::setMaxValue(float val)
    134 {
    135     if(fabs(m_maxValue - val) > 0.0001){
    136         m_maxValue = val;
    137         emit maxValueChanged(val);
    138     }
    139 }
    140  
    141 void DoubleSlider::setLabel(const QString& label)
    142 {
    143    m_label = label;
    144    update();
    145 }
    146  
    147 void DoubleSlider::leaveEvent(QEvent* event)
    148 {
    149     QWidget::leaveEvent(event);
    150     m_state = None;
    151     update();
    152 }
    153  
    154 float DoubleSlider::minRange() const
    155 {
    156     return m_min;
    157 }
    158 float DoubleSlider::maxRange() const
    159 {
    160     return m_max;
    161 }
    162  
    163  
    164 void DoubleSlider::mousePressEvent(QMouseEvent* event)
    165 {
    166     if(minHandleRegion.contains(event->pos())){
    167         m_state = MinHandle;
    168     }else if(maxHandleRegion.contains(event->pos())){
    169         m_state = MaxHandle;
    170     }else{
    171         m_state = None;
    172     }
    173  
    174     if(fabs(minValue() - maxValue()) < 0.001){
    175         if(fabs(minValue() - m_min) < 0.001){
    176             m_state = MaxHandle;
    177         }else if(fabs(minValue() - m_max) < 0.001){
    178             m_state = MinHandle;
    179         }else{}
    180     }
    181  
    182     update();
    183 }
    184  
    185 void DoubleSlider::mouseMoveEvent(QMouseEvent* event)
    186 {
    187     if(event->buttons() & Qt::LeftButton){
    188         float move = event->x() * (m_max - m_min) * 1.0/ width() + m_min;
    189  
    190         switch(m_state){
    191             case MinHandle:{
    192                 float val = getValidValue( move, m_min,maxValue());
    193                 setMinValue(val);
    194                 break;
    195             }
    196  
    197             case MaxHandle:{
    198                     float val = getValidValue(move, minValue(), m_max);
    199                     setMaxValue(val);
    200                     break;
    201             }
    202             case None:default: break;
    203         }
    204     }
    205     update();
    206 }
    207  
    208  
    209 void DoubleSlider::keyPressEvent(QKeyEvent *event)
    210 {
    211     QWidget::keyPressEvent(event);
    212  
    213     if(event->key() == Qt::Key_Left){
    214         if(m_state == MinHandle){
    215             float val = getValidValue(minValue()- m_singleStep, m_min ,maxValue());
    216             setMinValue(val);
    217         }else if(m_state == MaxHandle) {
    218             float val = getValidValue(maxValue()- m_singleStep, minValue() ,m_max);
    219             setMaxValue(val);
    220         }else{}
    221     }else if(event->key() == Qt::Key_Right){
    222         if(m_state == MinHandle){
    223             float val = getValidValue(minValue() + m_singleStep, m_min ,maxValue());
    224             setMinValue(val);
    225         }else if(m_state == MaxHandle) {
    226             float val = getValidValue(maxValue() + m_singleStep, minValue() ,m_max);
    227             setMaxValue(val);
    228         }else{}
    229     }
    230  
    231     update();
    232  
    233 }
  • 相关阅读:
    分享ASP.NET+jQuery MiniUI后台购物管理
    ASP.NET发送电子邮件
    LINQ学习(三):Where子句
    ASP.NET配置KindEditor文本编辑器
    一步步写自己SqlHelper类库(五):Command对象
    ASP.NET生成静态页面的简单实现
    兼职开发悟出的点点滴滴
    设计模式学习笔记
    if else替代者
    ASP.NET 一生命周期中的额事件
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/13813001.html
Copyright © 2020-2023  润新知