Qt 自定义 转盘 控件[纯代码]

一 结果图示

 

 二 头文件

#ifndef DASHBOARD_H
#define DASHBOARD_H

#include <QWidget>
#include <QPainter>
#include <QtMath>
#include <QDebug>

class DashBoard : public QWidget
{
    Q_OBJECT
public:

    explicit DashBoard(QWidget *parent = nullptr);
    ~DashBoard();
    void setRange(double minValue, double maxValue);            //设置刻度范围
    void setValue(double value);                                //设置值
    void setValue(int value);                                   //设置值
    void setPrecision(int precision);                           //设置精确度,小数点后几位
    void setScaleMajor(int scaleMajor);                         //设置大刻度数量
    void setScaleMinor(int scaleMinor);                         //设置小刻度数量
    void setOuterCircleColor(const QColor &outerCircleColor);   //设置外圆背景颜色
    void setInnerCircleColor(const QColor &innerCircleColor);   //设置内圆背景颜色
    void setPieColor(const QColor &pieColor);                   //设置当前值扇形的颜色
    void setScaleColor(const QColor &scaleColor);               //设置刻度尺颜色
    void setPointerColor(const QColor &pointerColor);           //设置指针颜色
    void setTextColor(const QColor &textColor);                 //设置文本颜色
    void setShowOverlay(bool showOverlay);                      //设置是否显示外罩层
    void setOverlayColor(const QColor &overlayColor);           //设置外罩层颜色

protected:

    void paintEvent(QPaintEvent *);                 //绘制事件重写
    void drawOuterCircle(QPainter *painter);        //画外圆
    void drawInnerCircle(QPainter *painter);        //画内圆
    void drawScale(QPainter *painter);              //画刻度
    void drawScaleNum(QPainter *painter);           //画刻度值
    void drawOverlay(QPainter *painter);            //画外罩
    void drawValuePie(QPainter *painter);           //画扇形值
    void drawPointerTriangle(QPainter *painter);    //画三角指针
    void drawValue(QPainter *painter);              //画值

private:

    QColor m_outerCircleColor;          //外圆背景颜色
    QColor m_innerCircleColor;          //内圆背景颜色
    QColor m_scaleColor;                //刻度值颜色
    QColor m_pieColorValue;             //当前值颜色
    QColor m_pointerColor;              //指针颜色
    QColor m_overlayColor;              //遮罩层颜色
    QColor m_textColor;                 //文本颜色

    double m_minValue = 0;              //最小值
    double m_maxValue = 100;            //最大值
    double m_value = 0;                //当前值
    int m_precision = 0;                //精确度,小数点后几位
    int m_startAngle = 0;               //开始旋转角度
    int m_endAngle = 0;                 //结束旋转角度
    int m_scaleMajor = 10;              //大刻度数量
    int m_scaleMinor = 10;              //小刻度数量

    bool m_showOverlay = true;          //显示遮罩层

};

#endif // DASHBOARD_H

三 源代码
#include "dashboard.h"

DashBoard::DashBoard(QWidget *parent) : QWidget(parent)
{
    m_outerCircleColor = QColor(210, 210, 210);
    m_innerCircleColor = QColor(255, 255, 255);
    m_scaleColor = QColor(56, 119, 246);
    m_overlayColor = QColor(217, 100, 255);
    m_pieColorValue = QColor(56, 119, 246);
    m_pointerColor = QColor(255, 0, 0);
    m_textColor = QColor(12, 29, 62);
}

DashBoard::~DashBoard()
{

}

//重写绘制事件
void DashBoard::paintEvent(QPaintEvent *)
{

    int width = this->width();
    int height = this->height();
    int side = qMin(width, height);
    QPainter painter(this);
    painter.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);//设置给定的渲染提示;
    painter.translate(width / 2, height / 2);//平移
    painter.scale(side / 200.0, side / 200.0);//将坐标系缩放

    drawOuterCircle(&painter);      //画外圆
    drawScale(&painter);            //画刻度
    drawScaleNum(&painter);         //画刻度值
    drawOverlay(&painter);          //画外罩
    drawValuePie(&painter);         //画扇形
    drawInnerCircle(&painter);      //画内圆 遮住扇形一部分 成饼形
    drawPointerTriangle(&painter);  //画指针
    drawValue(&painter);            //画值
}

//外圆
void DashBoard::drawOuterCircle(QPainter *painter)
{
    int radius = 65;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(m_outerCircleColor);
    painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
    painter->restore();
}

//内圆
void DashBoard::drawInnerCircle(QPainter *painter)
{
    int radius = 50;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(m_innerCircleColor);
    painter->drawEllipse(-radius, -radius, radius * 2, radius * 2);
    painter->restore();
}

//画刻度
void DashBoard::drawScale(QPainter *painter)
{
    int radius = 80;
    painter->save();

    painter->rotate(m_startAngle);
    int steps = (m_scaleMajor * m_scaleMinor);
    double angleStep = (360.0 - m_startAngle - m_endAngle) / steps;

    QPen pen;
    pen.setColor(m_scaleColor);
    pen.setCapStyle(Qt::RoundCap);

    for (int i = 0; i <= steps; i++) {
        if (i % m_scaleMinor == 0) {
            pen.setWidthF(1.5);
            painter->setPen(pen);
            painter->drawLine(0, radius - 10, 0, radius);
        } else {
            pen.setWidthF(0.5);
            painter->setPen(pen);
            painter->drawLine(0, radius - 10, 0, radius-5);
        }
        painter->rotate(angleStep);
    }

    painter->restore();
}

//画刻度值
void DashBoard::drawScaleNum(QPainter *painter)
{
    int radius = 90;
    painter->save();
    painter->setPen(m_scaleColor);

    double startRad = (360 - m_startAngle - 90) * (M_PI / 180);
    double deltaRad = (360 - m_startAngle - m_endAngle) * (M_PI / 180) / m_scaleMajor;

    for (int i = 0; i < m_scaleMajor; i++)
    {
        double sina = qSin(startRad - i * deltaRad);
        double cosa = qCos(startRad - i * deltaRad);
        double value = 1.0 * i * ((m_maxValue - m_minValue) / m_scaleMajor) + m_minValue;

        //QString strValue = QString("%1").arg((double)value, 0, 'f', m_precision);
        QString strValue = QString("%1").arg(static_cast<double>(value), 0, 'f', 0);
        double textWidth = fontMetrics().width(strValue);
        double textHeight = fontMetrics().height();
        int x = static_cast<int>(radius * cosa - textWidth / 2);
        int y = static_cast<int>(-radius * sina + textHeight / 4);
        painter->drawText(x, y, strValue);
    }

    painter->restore();
}

//画外罩
void DashBoard::drawOverlay(QPainter *painter)
{
    if (!m_showOverlay) {
        return;
    }

    int radius = 100;
    painter->save();
    painter->setPen(Qt::NoPen);

    QPainterPath smallCircle;
    QPainterPath bigCircle;
    radius -= 1;
    smallCircle.addEllipse(-radius, -radius, radius * 2, radius * 2);
    radius *= 2;
    bigCircle.addEllipse(-radius, -radius + 140, radius * 2, radius * 2);

    //高光的形状为小圆扣掉大圆的部分
    QPainterPath highlight = smallCircle - bigCircle;

    QLinearGradient linearGradient(0, -radius / 2, 0, 0);
    m_overlayColor.setAlpha(100);
    linearGradient.setColorAt(0.0, m_overlayColor);
    m_overlayColor.setAlpha(30);
    linearGradient.setColorAt(1.0, m_overlayColor);
    painter->setBrush(linearGradient);
    painter->rotate(-20);
    painter->drawPath(smallCircle);

    painter->restore();
}

//画扇形
void DashBoard::drawValuePie(QPainter *painter)
{
    int radius = 65;
    painter->save();
    painter->setPen(Qt::NoPen);
    QRectF rect(-radius, -radius, radius * 2, radius * 2);
    double angle = (m_value / m_maxValue) * 360;

    //绘制开始饼圆
    painter->setBrush(m_pieColorValue);
    painter->drawPie(rect, -90 * 16, static_cast<int>(-angle * 16));//三点钟为0点

    painter->restore();
}
//指针
void DashBoard::drawPointerTriangle(QPainter *painter)
{
    int radius = 10;
    int offset = 39;
    painter->save();
    painter->setPen(Qt::NoPen);
    painter->setBrush(m_pointerColor);

    QPolygon pts;
    pts.setPoints(3, -5, 0 + offset, 5, 0 + offset, 0, radius + offset);

    painter->rotate(m_startAngle);
    double degRotate = (360.0 - m_startAngle - m_endAngle) / (m_maxValue - m_minValue) * (m_value - m_minValue);
    painter->rotate(degRotate);
    painter->drawConvexPolygon(pts);

    painter->restore();
}

//画文本
void DashBoard::drawValue(QPainter *painter)
{
    int radius = 100;
    painter->save();
    painter->setPen(m_textColor);

    QFont font;
    font.setPixelSize(24);
    painter->setFont(font);

    QRectF textRect(-radius, -radius, radius * 2, radius * 2);
    QString strValue = QString("%1um").arg((double)m_value, 0, 'f', m_precision);
    painter->drawText(textRect, Qt::AlignCenter, strValue);

    painter->restore();
}

//设置刻度范围
void DashBoard::setRange(double minValue, double maxValue)
{
    m_minValue = minValue;
    m_maxValue = maxValue;
    update();
}

//设置值
void DashBoard::setValue(double value)
{
    m_value = value;
    update();
}

//设置值
void DashBoard::setValue(int value)
{
    m_value = value;
    update();
}

//设置精确度
void DashBoard::setPrecision(int precision)
{
    m_precision = precision;
    update();
}

//设置大刻度数量
void DashBoard::setScaleMajor(int scaleMajor)
{
    m_scaleMajor = scaleMajor;
    update();
}

//设置小刻度数量
void DashBoard::setScaleMinor(int scaleMinor)
{
    m_scaleMinor = scaleMinor;
    update();
}

//设置外圆颜色
void DashBoard::setOuterCircleColor(const QColor &outerCircleColor)
{
    m_outerCircleColor = outerCircleColor;
    update();
}

//设置内圆颜色
void DashBoard::setInnerCircleColor(const QColor &innerCircleColor)
{
    m_innerCircleColor = innerCircleColor;
    update();
}

//设置饼形颜色
void DashBoard::setPieColor(const QColor &pieColor)
{
    m_pieColorValue = pieColor;
    update();
}

//设置刻度尺颜色
void DashBoard::setScaleColor(const QColor &scaleColor)
{
    m_scaleColor = scaleColor;
    update();
}

//设置指针颜色
void DashBoard::setPointerColor(const QColor &pointerColor)
{
    m_pointerColor = pointerColor;
    update();
}

//设置文本颜色
void DashBoard::setTextColor(const QColor &textColor)
{
    m_textColor = textColor;
    update();
}

//设置是否显示外罩
void DashBoard::setShowOverlay(bool showOverlay)
{
    m_showOverlay = showOverlay;
    update();
}


posted @ 2021-03-17 09:09  一笔一世界  阅读(820)  评论(0编辑  收藏  举报