Qt5 雙滑塊支援float變化的控制元件,以及單滑塊float控制元件,供大家參考
阿新 • • 發佈:2019-02-11
#ifndef DOUBLESLIDER_H #define DOUBLESLIDER_H #include class DoubleSlider : public QWidget { Q_OBJECT public: 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(); }