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 }

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM