diff --git a/src/exquisite/qqtcustomsliderruler.cpp b/src/exquisite/qqtcustomsliderruler.cpp new file mode 100644 index 00000000..b4c82b35 --- /dev/null +++ b/src/exquisite/qqtcustomsliderruler.cpp @@ -0,0 +1,344 @@ +#include "qqtcustomsliderruler.h" +#include "qpainter.h" +#include "qevent.h" +#include "qtimer.h" +#include "qdebug.h" + +QQtCustomSliderRuler::QQtCustomSliderRuler(QWidget* parent) : + QWidget(parent) +{ + value = 0.0; + minValue = 0.0; + maxValue = 100.0; + + precision = 0; + longStep = 10; + shortStep = 1; + space = 20; + + bgColorStart = QColor(100, 100, 100); + bgColorEnd = QColor(60, 60, 60); + lineColor = QColor(255, 255, 255); + + sliderColorTop = QColor(100, 184, 255); + sliderColorBottom = QColor(235, 235, 235); + + tipBgColor = QColor(255, 255, 255); + tipTextColor = QColor(50, 50, 50); + + pressed = false; + currentValue = 0; + sliderLastPot = QPointF(space, longLineHeight / 2); +} + +void QQtCustomSliderRuler::resizeEvent(QResizeEvent*) +{ + resetVariables(); + setValue(currentValue); +} + +void QQtCustomSliderRuler::wheelEvent(QWheelEvent* e) +{ + /*滚动的角度,*8就是鼠标滚动的距离*/ + int degrees = e->delta() / 8; + + /*滚动的步数,*15就是鼠标滚动的角度*/ + int steps = degrees / 15; + + /*如果是正数代表为左边移动,负数代表为右边移动*/ + if (e->orientation() == Qt::Vertical) + { + double value = currentValue - steps; + + if (steps > 0) + { + if (value > minValue) + { + setValue(value); + } + else + { + setValue(minValue); + } + } + else + { + if (value < maxValue) + { + setValue(value); + } + else + { + setValue(maxValue); + } + } + } +} + +void QQtCustomSliderRuler::mousePressEvent(QMouseEvent* e) +{ + if (e->button() & Qt::LeftButton) + { + if (sliderRect.contains(e->pos())) + { + pressed = true; + update(); + } + } +} + +void QQtCustomSliderRuler::mouseReleaseEvent(QMouseEvent* e) +{ + pressed = false; + update(); +} + +void QQtCustomSliderRuler::mouseMoveEvent(QMouseEvent* e) +{ + if (pressed) + { + if (e->pos().x() >= lineLeftPot.x() && e->pos().x() <= lineRightPot.x()) + { + double totalLineWidth = lineRightPot.x() - lineLeftPot.x(); + double dx = e->pos().x() - lineLeftPot.x(); + double ratio = (double)dx / totalLineWidth; + sliderLastPot = QPointF(e->pos().x(), sliderTopPot.y()); + + currentValue = (maxValue - minValue) * ratio + minValue; + this->value = currentValue; + emit valueChanged(currentValue); + update(); + } + } +} + +void QQtCustomSliderRuler::paintEvent(QPaintEvent*) +{ + /*绘制准备工作,启用反锯齿*/ + QPainter painter(this); + painter.setRenderHint(QPainter::Antialiasing); + + /*绘制背景*/ + drawBg(&painter); + /*绘制标尺*/ + drawRule(&painter); + /*绘制滑块*/ + drawSlider(&painter); + /*绘制当前值的提示*/ + drawTip(&painter); +} + +void QQtCustomSliderRuler::drawBg(QPainter* painter) +{ + painter->save(); + painter->setPen(Qt::NoPen); + QLinearGradient bgGradient(0, 0, 0, height()); + bgGradient.setColorAt(0.0, bgColorStart); + bgGradient.setColorAt(1.0, bgColorEnd); + painter->setBrush(bgGradient); + painter->drawRect(rect()); + painter->restore(); +} + +void QQtCustomSliderRuler::drawRule(QPainter* painter) +{ + painter->save(); + painter->setPen(lineColor); + + /*绘制横向标尺底部线,居中*/ + double initX = space; + double initY = (double)height() / 2; + lineLeftPot = QPointF(initX, initY); + lineRightPot = QPointF(width() - initX, initY); + painter->drawLine(lineLeftPot, lineRightPot); + + /*绘制纵向标尺刻度 */ + double length = width() - 2 * space; + /*计算每一格移动多少*/ + double increment = length / (maxValue - minValue); + + /*根据范围值绘制刻度值及刻度值*/ + for (int i = minValue; i <= maxValue; i = i + shortStep) + { + if (i % longStep == 0) + { + QPointF topPot(initX, initY - longLineHeight); + QPointF bottomPot(initX, initY); + painter->drawLine(topPot, bottomPot); + + QString strValue = QString("%1").arg((double)i, 0, 'f', precision); + double textWidth = fontMetrics().width(strValue); + double textHeight = fontMetrics().height(); + QPointF textPot(initX - textWidth / 2, initY + textHeight); + painter->drawText(textPot, strValue); + } + else + { + QPointF topPot(initX, initY - shortLineHeight); + QPointF bottomPot(initX, initY); + painter->drawLine(topPot, bottomPot); + } + + initX += increment * shortStep; + } + + painter->restore(); +} + +void QQtCustomSliderRuler::drawSlider(QPainter* painter) +{ + painter->save(); + + /*绘制滑块上部分三角形*/ + sliderTopPot = QPointF(sliderLastPot.x(), lineLeftPot.y() - longLineHeight / 4); + sliderLeftPot = QPointF(sliderTopPot.x() - width() / 100, sliderTopPot.y() + sliderTopHeight); + sliderRightPot = QPointF(sliderTopPot.x() + width() / 100, sliderTopPot.y() + sliderTopHeight); + + painter->setPen(sliderColorTop); + painter->setBrush(sliderColorTop); + + QVector potVec; + potVec.append(sliderTopPot); + potVec.append(sliderLeftPot); + potVec.append(sliderRightPot); + painter->drawPolygon(potVec); + + /*绘制滑块下部分矩形*/ + double indicatorLength = sliderRightPot.x() - sliderLeftPot.x(); + + QPointF handleBottomRightPot(sliderLeftPot.x() + indicatorLength, sliderLeftPot.y() + sliderBottomHeight); + sliderRect = QRectF(sliderLeftPot, handleBottomRightPot); + + QPointF tipRectTopLeftPot(sliderRect.topRight().x() + 2, sliderRect.topRight().y()); + QString strValue = QString("%1").arg(currentValue, 0, 'f', precision); + + double textLength = fontMetrics().width(strValue); + double textHeight = fontMetrics().height(); + QPointF tipRectBottomRightPot(tipRectTopLeftPot.x() + textLength + 10, tipRectTopLeftPot.y() + textHeight + 5); + tipRect = QRectF(tipRectTopLeftPot, tipRectBottomRightPot); + + painter->setPen(sliderColorBottom); + painter->setBrush(sliderColorBottom); + painter->drawRect(sliderRect); + painter->restore(); +} + +void QQtCustomSliderRuler::drawTip(QPainter* painter) +{ + if (!pressed) + { + return; + } + + painter->save(); + painter->setPen(tipTextColor); + painter->setBrush(tipBgColor); + painter->drawRect(tipRect); + QString strValue = QString("%1").arg(currentValue, 0, 'f', precision); + painter->drawText(tipRect, Qt::AlignCenter, strValue); + painter->restore(); +} + +void QQtCustomSliderRuler::resetVariables() +{ + longLineHeight = height() / 5; + shortLineHeight = height() / 7; + sliderTopHeight = height() / 7; + sliderBottomHeight = height() / 6; +} + +void QQtCustomSliderRuler::setRange(double minValue, double maxValue) +{ + /*如果最小值大于或者等于最大值以及最小值小于0则不设置*/ + if (minValue >= maxValue || minValue < 0) + { + return; + } + + this->minValue = minValue; + this->maxValue = maxValue; + setValue(minValue); +} + +void QQtCustomSliderRuler::setRange(int minValue, int maxValue) +{ + setRange((double)minValue, (double)maxValue); +} + +void QQtCustomSliderRuler::setValue(double value) +{ + /*值小于最小值或者值大于最大值则无需处理*/ + if (value < minValue || value > maxValue) + { + return; + } + + double lineWidth = width() - 2 * space; + double ratio = (double)value / (maxValue - minValue); + double x = lineWidth * ratio; + double newX = x + space; + double y = space + longLineHeight - 10; + sliderLastPot = QPointF(newX, y); + + this->value = value; + this->currentValue = value; + emit valueChanged(value); + update(); +} + +void QQtCustomSliderRuler::setValue(int value) +{ + setValue((double)value); +} + +void QQtCustomSliderRuler::setPrecision(int precision) +{ + this->precision = precision; + update(); +} + +void QQtCustomSliderRuler::setStep(int longStep, int shortStep) +{ + /*短步长不能超过长步长*/ + if (longStep < shortStep) + { + return; + } + + this->longStep = longStep; + this->shortStep = shortStep; + update(); +} + +void QQtCustomSliderRuler::setSpace(int space) +{ + this->space = space; + update(); +} + +void QQtCustomSliderRuler::setBgColor(QColor bgColorStart, QColor bgColorEnd) +{ + this->bgColorStart = bgColorStart; + this->bgColorEnd = bgColorEnd; + update(); +} + +void QQtCustomSliderRuler::setLineColor(QColor lineColor) +{ + this->lineColor = lineColor; + update(); +} + +void QQtCustomSliderRuler::setSliderColor(QColor sliderColorTop, QColor sliderColorBottom) +{ + this->sliderColorTop = sliderColorTop; + this->sliderColorBottom = sliderColorBottom; + update(); +} + +void QQtCustomSliderRuler::setTipBgColor(QColor tipBgColor, QColor tipTextColor) +{ + this->tipBgColor = tipBgColor; + this->tipTextColor = tipTextColor; + update(); +} diff --git a/src/exquisite/qqtcustomsliderruler.h b/src/exquisite/qqtcustomsliderruler.h new file mode 100644 index 00000000..6be87db5 --- /dev/null +++ b/src/exquisite/qqtcustomsliderruler.h @@ -0,0 +1,170 @@ +#ifndef __QQTCUSTOMSLIDERRULER_H__ +#define __QQTCUSTOMSLIDERRULER_H__ + +/** + * T.D.R (QQ:2657635903) MOD 2017年10月21日13:24:03 +**/ + +/** + * 作者:feiyangqingyun(QQ:517216493) 2016-10-28 + * 本控件来源于网络(原作者:kimtaikee(http://www.qtcn.org/bbs/read-htm-tid-33719-ds-1.html#tpc)) + * 1:增加设置精确度(小数点后几位)和间距 + * 2:增加设置背景色/滑块颜色/提示信息背景前景色 + * 3:增加鼠标滚轮支持 + * 4:增加设置长线条步长及短线条步长 + * 5:移除定时器实现显示和隐藏提示值 + * 6:增加设置范围值 + * 7:暂不支持负数刻度值 + */ + +#include + +class QQtCustomSliderRuler : public QWidget +{ + Q_OBJECT +public: + explicit QQtCustomSliderRuler(QWidget* parent = 0); + +protected: + void resizeEvent(QResizeEvent*); + void wheelEvent(QWheelEvent*); + void mousePressEvent(QMouseEvent*); + void mouseReleaseEvent(QMouseEvent*); + void mouseMoveEvent(QMouseEvent*); + void paintEvent(QPaintEvent*); + void drawBg(QPainter* painter); + void drawRule(QPainter* painter); + void drawSlider(QPainter* painter); + void drawTip(QPainter* painter); + +private: + double value; /*目标值*/ + double maxValue; /*最小值*/ + double minValue; /*最大值*/ + int precision; /*精确度,小数点后几位*/ + int longStep; /*长线条等分步长*/ + int shortStep; /*短线条等分步长*/ + int space; /*间距*/ + + QColor bgColorStart; /*背景渐变开始颜色*/ + QColor bgColorEnd; /*背景渐变结束颜色*/ + QColor lineColor; /*线条颜色*/ + + QColor sliderColorTop; /*滑块上部颜色*/ + QColor sliderColorBottom; /*滑块下部颜色*/ + + QColor tipBgColor; /*当前值背景色*/ + QColor tipTextColor; /*当前值文字颜色*/ + + bool pressed; /*是否鼠标按下*/ + double currentValue; /*当前值*/ + + double longLineHeight; /*长刻度高度*/ + double shortLineHeight; /*短刻度高度*/ + double sliderTopHeight; /*滑块上部高度*/ + double sliderBottomHeight; /*滑块底部高度*/ + + QPointF sliderLastPot; /*滑块最后的坐标*/ + QPointF sliderTopPot; /*滑块顶部坐标*/ + QPointF sliderLeftPot; /*滑块左边坐标*/ + QPointF sliderRightPot; /*滑块右边坐标*/ + + QRectF sliderRect; /*滑块矩形区域*/ + QRectF tipRect; /*提示信息矩形区域*/ + QPointF lineLeftPot; /*主线左边坐标*/ + QPointF lineRightPot; /*主线右边坐标*/ + +private slots: + void resetVariables(); + +public: + double getValue() const + { + return value; + } + double getMinValue() const + { + return minValue; + } + double getMaxValue() const + { + return maxValue; + } + + int getPrecision() const + { + return precision; + } + int getLongStep() const + { + return longStep; + } + int getShortStep() const + { + return shortStep; + } + int getSpace() const + { + return space; + } + + QColor getBgColorStart() const + { + return bgColorStart; + } + QColor getBgColorEnd() const + { + return bgColorEnd; + } + QColor getLineColor() const + { + return lineColor; + } + + QColor getSliderColorTop() const + { + return sliderColorTop; + } + QColor getSliderColorBottom() const + { + return sliderColorBottom; + } + + QColor getTipBgColor() const + { + return tipBgColor; + } + QColor getTipTextColor() const + { + return tipTextColor; + } +public slots: + /*设置最大最小值-范围值*/ + void setRange(double minValue, double maxValue); + void setRange(int minValue, int maxValue); + + /*设置目标值*/ + void setValue(double value); + void setValue(int value); + + /*设置精确度*/ + void setPrecision(int precision); + /*设置线条等分步长*/ + void setStep(int longStep, int shortStep); + /*设置间距*/ + void setSpace(int space); + + /*设置背景颜色*/ + void setBgColor(QColor bgColorStart, QColor bgColorEnd); + /*设置线条颜色*/ + void setLineColor(QColor lineColor); + /*设置滑块颜色*/ + void setSliderColor(QColor sliderColorTop, QColor sliderColorBottom); + /*设置提示信息背景*/ + void setTipBgColor(QColor tipBgColor, QColor tipTextColor); + +signals: + void valueChanged(double value); +}; + +#endif /* __QQTCUSTOMSLIDERRULER_H__ diff --git a/src/qqt_source.pri b/src/qqt_source.pri index d1004797..718f1a27 100644 --- a/src/qqt_source.pri +++ b/src/qqt_source.pri @@ -26,10 +26,12 @@ win32 { SOURCES = \ $$PWD/exquisite/qqtcustomprogressbar.cpp \ - $$PWD/exquisite/qqtcustomspeedmeter.cpp + $$PWD/exquisite/qqtcustomspeedmeter.cpp \ + $$PWD/exquisite/qqtcustomsliderruler.cpp HEADERS = \ $$PWD/exquisite/qqtcustomprogressbar.h \ - $$PWD/exquisite/qqtcustomspeedmeter.h + $$PWD/exquisite/qqtcustomspeedmeter.h \ + $$PWD/exquisite/qqtcustomsliderruler.h #root dir win32 {