单滑块代码
#ifndef FLOATSLIDER_H
#define FLOATSLIDER_H
#include
class FloatSlider : public QWidget
{
Q_OBJECT
public:
explicit FloatSlider(QWidget *parent = 0);
void setRange(float min, float max);
void setSingleStep(float step);
float minRange() const;
float maxRange() const;
float value() const;
enum State{ Hovered,None};
public slots:
void setLabel(const QString& label);
void setValue(float val);
signals:
void valueChanged(float);
private:
float m_min;
float m_max;
float m_singleStep;
float m_value;
QRect handleRegion;
QString m_label;
State m_state;
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 // FLOATSLIDER_H
#include "floatslider.h"
#include
#include
FloatSlider::FloatSlider(QWidget *parent)
: QWidget(parent)
, m_min(0.0f)
, m_max(99.0f)
, m_singleStep(0.1f)
, m_state(None)
{
setFocusPolicy(Qt::StrongFocus);
setFixedHeight(50);
}
void FloatSlider::setRange(float min, float max)
{
m_min = min;
m_max = max;
float val = std::min(m_value,m_max);
val = std::max(val,m_min);
setValue(val);
}
void FloatSlider::setSingleStep(float step)
{
m_singleStep = step;
}
float FloatSlider::minRange() const
{
return m_min;
}
float FloatSlider::maxRange() const
{
return m_max;
}
float FloatSlider::value() const
{
return m_value;
}
void FloatSlider::setLabel(const QString& label)
{
m_label = label;
update();
}
void FloatSlider::setValue(float val)
{
if(fabs(m_value - val) > (m_singleStep / 100)){
m_value = val;
emit valueChanged(val);
update();
}
}
void FloatSlider::leaveEvent(QEvent* event)
{
QWidget::leaveEvent(event);
m_state = None;
update();
}
void FloatSlider::paintEvent(QPaintEvent* event)
{
QWidget::paintEvent(event);
QPainter painter(this);
paintValueLabel(&painter);
}
void FloatSlider::paintColoredRect(QRect rect, QColor color ,QPainter* painter)
{
painter->fillRect(rect,QBrush(color));
}
void FloatSlider::paintValueLabel(QPainter* painter)
{
painter->setBrush(Qt::NoBrush);
painter->setPen(Qt::black);
painter->setFont(QFont("Arial",12));
QString valueString = QString::number(m_value,'f',3);
QFontMetrics metrics = painter->fontMetrics();
int textWidth = metrics.width(valueString);
int textHeight = metrics.height();
//---- paint text
painter->drawText(QRectF(2,4,textWidth,textHeight),valueString);
//----- 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_value - m_min ) * width() / (m_max - m_min);
if(minPos <= 4){
minPos = 4;
}else if(minPos >= width() - 8){
minPos = width() - 8;
}else{}
//----- paint groove
paintColoredRect(QRect(4,37,width() - 8,2),Qt::gray,painter);
paintColoredRect(QRect(4,37,minPos,2),QColor(51,153,155),painter);
//----- handle
handleRegion = QRect(minPos ,30,8,16);
//-----paint Handle
QColor minColor = (m_state == Hovered) ? QColor(51,153,155) : Qt::darkGray;
paintColoredRect(handleRegion,minColor,painter);
}
void FloatSlider::mousePressEvent(QMouseEvent* event)
{
if(handleRegion.contains(event->pos())){
m_state = Hovered;
}else{
m_state = None;
}
update();
}
inline float getValidValue(float val, float min, float max)
{
float tmp = std::max(val, min);
return std::min(tmp, max);
}
void FloatSlider::mouseMoveEvent(QMouseEvent* event)
{
if(event->buttons() & Qt::LeftButton){
float move = event->x() * (m_max - m_min) * 1.0/ width() + m_min;
if(m_state == Hovered){
float val = getValidValue( move, m_min,m_max);
setValue(val);
}
}
update();
}
void FloatSlider::keyPressEvent(QKeyEvent *event)
{
QWidget::keyPressEvent(event);
if(m_state == Hovered){
float move = 0;
if(event->key() == Qt::Key_Left){
move = - m_singleStep;
}else if(event->key() == Qt::Key_Right){
move = m_singleStep;
}else{}
float val = getValidValue(value() + move, m_min, m_max);
setValue(val);
}
update();
}