#include "rangeslider.h" #include #include #include RangeSlider::RangeSlider(int style,QWidget *parent) : QWidget(parent) { setMinimumSize(20, 240); } void RangeSlider::setRange(int min, int max) { m_min = min; m_max = max; m_lower = qBound(m_min, m_lower, m_max); m_upper = qBound(m_lower, m_upper, m_max); update(); } void RangeSlider::setSliderWidth(int width) { sliderWidth = width; update(); // 更新界面 } float RangeSlider::lowerValue() const { return m_lower; } float RangeSlider::upperValue() const { return m_upper; } float RangeSlider::valueToY(float value) const { double ratio = (value - m_min) / double(m_max - m_min); return height() - handleRadius - ratio * (height() - 2 * handleRadius); } float RangeSlider::yToValue(float y) const { double ratio = (height() - handleRadius - y) / double(height() - 2 * handleRadius); ratio = qBound(0.0, ratio, 1.0); float rawValue = m_min + ratio * (m_max - m_min); float steppedValue = qRound(rawValue * 10) / 10.0f; return qBound(m_min, steppedValue, m_max); } RangeSlider::HandleType RangeSlider::handleHitTest(float y) const { int yLower = valueToY(m_lower); int yUpper = valueToY(m_upper); if (qAbs(y - yLower) <= handleRadius + 2) return LowerHandle; if (qAbs(y - yUpper) <= handleRadius + 2) return UpperHandle; return NoHandle; } void RangeSlider::mousePressEvent(QMouseEvent *event) { currentHandle = handleHitTest(event->pos().y()); } void RangeSlider::mouseMoveEvent(QMouseEvent *event) { if (currentHandle == NoHandle) return; float val = yToValue(event->pos().y()); if (currentHandle == LowerHandle) { m_lower = qBound(m_min, val, m_upper); } else if (currentHandle == UpperHandle) { m_upper = qBound(m_lower, val, m_max); } update(); emit rangeChanged(m_lower, m_upper); } void RangeSlider::mouseReleaseEvent(QMouseEvent *) { currentHandle = NoHandle; } void RangeSlider::paintEvent(QPaintEvent *) { QPainter p(this); p.setRenderHint(QPainter::Antialiasing); int x = width() / 2; int yLower = valueToY(m_lower); int yUpper = valueToY(m_upper); // Draw Temperature-style background (gradient) drawTemperatureStyle(&p); // Draw selected range (green) // Draw selected range (green) p.setPen(Qt::NoPen); p.setBrush(Qt::green); p.drawRect(x - sliderWidth / 2, yUpper, sliderWidth, yLower - yUpper); // Draw simple red handles (circles) p.setPen(Qt::NoPen); p.setBrush(Qt::red); p.drawEllipse(QPointF(x, yLower), handleRadius, handleRadius); p.drawEllipse(QPointF(x, yUpper), handleRadius, handleRadius); // Draw ticks drawTicks(&p); } void RangeSlider::setLowerValue(float val) { m_lower = qBound(m_min, val, m_upper); update(); emit rangeChanged(m_lower, m_upper); } void RangeSlider::setUpperValue(float val) { m_upper = qBound(m_lower, val, m_max); update(); emit rangeChanged(m_lower, m_upper); } void RangeSlider::drawTemperatureStyle(QPainter *p) { int x = width() / 2; int yTop = handleRadius; int yBottom = height() - handleRadius; // Draw border (black) p->setPen(Qt::black); p->setBrush(Qt::NoBrush); p->drawRect(x - sliderWidth / 2, yTop, sliderWidth, yBottom - yTop); // Draw yellow outside the range p->setBrush(Qt::yellow); p->drawRect(x - sliderWidth / 2, yTop, sliderWidth, valueToY(m_lower) - yTop); // Above lower range p->drawRect(x - sliderWidth / 2, valueToY(m_upper), sliderWidth, yBottom - valueToY(m_upper)); // Below upper range // Draw green inside the range p->setBrush(Qt::green); p->drawRect(x - sliderWidth / 2, valueToY(m_upper), sliderWidth, valueToY(m_lower) - valueToY(m_upper)); // Green area } void RangeSlider::drawTicks(QPainter *p) { int tickCount = 11; p->setPen(Qt::black); p->setFont(QFont("Arial", 8)); int x = width() / 2 + handleRadius + 4; for (int i = 0; i < tickCount; ++i) { int val = m_min + i * (m_max - m_min) / (tickCount - 1); int y = valueToY(val); p->drawLine(x, y, x + 3, y); // 刻度宽度 p->drawText(x + 8, y + 4, QString::number(val)); } }