当前位置:   article > 正文

Qt自定义控件-维度图/雷达图_qt 能力值 radar

qt 能力值 radar

Qt 自定义控件-维度图/雷达图

一、效果展示

在这里插入图片描述

二、头文件

#ifndef DIMENSIONCHARTWIDGET_H
#define DIMENSIONCHARTWIDGET_H

#include <QMap>
#include <QPen>
#include <QObject>
#include <QWidget>

class DimensionInfo;
class DimensionChartWidget : public QWidget
{
    Q_OBJECT

public:
    explicit DimensionChartWidget(QWidget *parent = nullptr);

    inline QColor backgroundColor() const { return m_backgroundColor; }
    inline void setBackgroundColor(const QColor &backgroundColor) { m_backgroundColor = backgroundColor; }

    inline float radius() const { return m_radius; }
    inline void setRadius(float radius) { m_radius = radius; }

    inline int sidesNumber() const { return m_sidesNumber; }
    inline void setSidesNumber(int sidesNumber) {m_sidesNumber = sidesNumber; }

    inline QPen sidesPen() const { return m_sidesPen; }
    inline void setSidesPen(const QPen &sidesPen) { m_sidesPen = sidesPen; }

    inline QVector<DimensionInfo> dimensionInfos() const { return m_dimensionInfos; }
    inline void setDimensionInfos(const QVector<DimensionInfo> &dimensionInfos) { m_dimensionInfos = dimensionInfos; }

    inline QPen textPen() const { return m_textPen; }
    inline void setTextPen(const QPen &textPen) { m_textPen = textPen; }

    inline QPen dimensionPen() const { return m_dimensionPen; }
    inline void setDimensionPen(const QPen &dimensionPen) { m_dimensionPen = dimensionPen; }

    inline QFont textFont() const { return m_textFont; }
    inline void setTextFont(const QFont &textFont) { m_textFont = textFont; }

    inline int filletRadius() const { return m_filletRadius; }
    inline void setFilletRadius(int filletRadius) { m_filletRadius = filletRadius; }

protected:
    void paintEvent(QPaintEvent*);
    void drawText(QPainter&, QPointF, QString text);
    void convertPoint(QPointF&);

private:
    QPen m_textPen;
    QPen m_sidesPen;
    QPen m_dimensionPen;
    QFont m_textFont;
    QColor m_backgroundColor;

    int m_filletRadius;
    float m_radius;
    int m_sidesNumber;
    QVector<DimensionInfo> m_dimensionInfos;
};


class DimensionInfo {
public:
    DimensionInfo() = default;
    DimensionInfo(QString text, float percentage) { m_text = text; m_percentage = percentage; }

    inline QString text() const { return m_text; }
    inline void setText(const QString &text) { m_text = text; }

    inline float percentage() const { return m_percentage; }
    inline void setPercentage(float percentage) { m_percentage = percentage; }

private:
    QString m_text;
    float m_percentage;
};
#endif // DIMENSIONCHARTWIDGET_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78

三、源文件

#include "DimensionChartWidget.h"
#include <QPainter>
#include <QtMath>
#include <QDebug>
#include <QPainterPath>

DimensionChartWidget::DimensionChartWidget(QWidget *parent) : QWidget(parent)
{
    m_radius = 0;
    m_sidesNumber = 1;
}

void DimensionChartWidget::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);

    painter.setPen(QColor(m_backgroundColor));
    painter.setBrush(QBrush(m_backgroundColor));
    painter.drawRoundedRect(rect(), m_filletRadius, m_filletRadius);

    // 绘图设备的坐标原点(0,0)在左上角,水平向右增长,垂直向下增长。
    // 将坐标系原点移动到界面中间
    painter.translate(width() / 2.0, height() / 2.0);

    // 设中心点到边的垂线与半径的夹角为degree=(360/count)/2
    float degree = 360.0 / m_dimensionInfos.size();

    // 开始绘制多边形,并为每个区域上色
    painter.setPen(m_sidesPen);
    QPointF lastPoint(0, -m_radius);
    QVector<QPointF> points;
    for(int i = 0; i < m_dimensionInfos.size(); i++)
    {
        float radian = qDegreesToRadians(degree * (i + 1));
        float x = m_radius * qSin(radian);
        float y = m_radius * qCos(radian);

        // 绘制该三角区块
        QPainterPath path;
        QPointF point(x, -y);
        path.lineTo(point);
        path.lineTo(lastPoint);
        path.lineTo(0, 0);
        painter.drawPath(path);

        //  绘制内线
        for(int j = m_sidesNumber - 1; j > 0; j--)
        {
            float multiple = (float)j / m_sidesNumber;
            painter.drawLine(point * multiple, lastPoint * multiple);
        }

        // 绘制文本
        painter.save();
        painter.setPen(m_textPen);
        painter.setFont(m_textFont);
        drawText(painter, point, m_dimensionInfos.at(i).text());
        painter.restore();

        lastPoint = point;
        points << point * m_dimensionInfos.at(i).percentage();
    }

    // 绘制维度信息
    painter.setPen(m_dimensionPen);
    QColor color = m_dimensionPen.color();
    color.setAlpha(150);
    painter.setBrush(QBrush(color));
    QPolygonF polygon(points);
    QPainterPath painterPath;
    painterPath.addPolygon(polygon);
    painter.drawPolygon(polygon);
}

/**
 * @brief DimensionChartWidget::drawText 绘制文本
 */
void DimensionChartWidget::drawText(QPainter& painter, QPointF point, QString text)
{
    //TODO // 这一部分要是有好的想法可以交流一下
    convertPoint(point);
    QRectF textRect;
    textRect.setSize(QSize(50, 30));
    int flag = Qt::AlignCenter;
    if(point.x() > 0)
    {
        if(point.y() < 0)
        {
            //x > 0 y < 0
//            textRect.moveCenter();
            textRect.setBottomLeft(point);
            textRect.setTopRight(QPoint(point.x() + 50, point.y() - 30));
            flag = Qt::AlignBottom | Qt::AlignLeft;
        }
        else if(point.y() > 0)
        {
            //x>0 y>0
            textRect.setTopLeft(point);
            textRect.setBottomRight(QPoint(point.x() + 50, point.y() + 30));
            flag = Qt::AlignTop | Qt::AlignLeft;
        }
        else
        {
            //x>0 y=0
            point.setY(point.y() - 15);
            textRect.setTopLeft(point);
            textRect.setBottomRight(QPoint(point.x() + 50, point.y() + 30));
            flag = Qt::AlignVCenter | Qt::AlignLeft;
        }
    }
    else if(point.x() < 0)
    {
        if(point.y() < 0)
        {
            //x<0 y<0
            textRect.setBottomRight(point);
            textRect.setTopLeft(QPoint(point.x() - 50, point.y() - 30));
            flag = Qt::AlignBottom | Qt::AlignRight;
        }
        else if(point.y() > 0)
        {
            //x<0 y>0
            textRect.setTopRight(point);
            textRect.setBottomLeft(QPoint(point.x() - 50, point.y() + 30));
            flag = Qt::AlignTop | Qt::AlignRight;
        }
        else
        {
            //x<0 y=0
            point.setY(point.y() - 15);
            textRect.setTopRight(point);
            textRect.setBottomLeft(QPoint(point.x() - 50, point.y() + 30));
            flag = Qt::AlignVCenter | Qt::AlignRight;
        }
    }
    else
    {
        if(point.y() < 0)
        {
            //x=0 y<0
            point.setX(point.x() - 25);
            textRect.setBottomRight(point);
            textRect.setTopLeft(QPoint(point.x() + 50, point.y() - 30));
            flag = Qt::AlignHCenter | Qt::AlignBottom;
        }
        else if(point.y() > 0)
        {
            //x=0 y>0
            point.setX(point.x() - 25);
            textRect.setTopLeft(point);
            textRect.setBottomRight(QPoint(point.x() + 50, point.y() + 30));
            flag = Qt::AlignHCenter | Qt::AlignTop;
        }
    }
    painter.drawText(textRect, flag, text);
}

/**
 * @brief DimensionChartWidget::convertPoint 通过三角函数换算的坐标在这里插入代码片误差大,这里对0进行校正
 * @param point 坐标
 */
void DimensionChartWidget::convertPoint(QPointF& point)
{
    if(qAbs(point.x()) < 0.001)
    {
        point.setX(0);
    }
    else if(qAbs(point.y()) < 0.001)
    {
        point.setY(0);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173

四、调用示例

pragma execution_character_set("utf-8")
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "DimensionChartWidget.h"
#include <QPen>
#include <QPainter>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setWindowTitle("维度图测试");
    this->resize(400, 400);
    initRadarChart();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    painter.setPen(QPen(QColor("#1A1A1A")));
    painter.setBrush(QBrush(QColor("#1A1A1A")));
    painter.drawRect(rect());
}

void MainWindow::initRadarChart()
{
    DimensionChartWidget* pDimensionChartWidget = new DimensionChartWidget(this);
    pDimensionChartWidget->resize(this->width() - 60, this->height() -60);
    pDimensionChartWidget->move(30, 30);

    // 设置维度网格数量
    pDimensionChartWidget->setSidesNumber(5);

    // 设置维度边长
    pDimensionChartWidget->setRadius(120);

    // 设置维度网格画笔
    QPen sidesPen;
    sidesPen.setColor(QColor("#003545"));
    sidesPen.setWidth(2);
    pDimensionChartWidget->setSidesPen(sidesPen);

    // 设置维度画笔
    QPen dimensionPen;
    dimensionPen.setColor(QColor("#0095C5"));
    dimensionPen.setWidth(3);
    pDimensionChartWidget->setDimensionPen(dimensionPen);

    // 设置字体信息
    QPen textPen;
    textPen.setColor(Qt::GlobalColor::white);
    pDimensionChartWidget->setTextPen(textPen);
    QFont textFont;
    textFont.setFamily("微软雅黑");
    textFont.setPointSize(10);
    pDimensionChartWidget->setTextFont(textFont);

    // 设置维度信息
    QVector<DimensionInfo> dimensionInfos;
    DimensionInfo dimensionInfo("维度1", 0.55);
    dimensionInfos.append(dimensionInfo);
    dimensionInfo.setText("维度2");
    dimensionInfo.setPercentage(0.85);
    dimensionInfos.append(dimensionInfo);
    dimensionInfo.setText("维度3");
    dimensionInfo.setPercentage(0.95);
    dimensionInfos.append(dimensionInfo);
    dimensionInfo.setText("维度4");
    dimensionInfo.setPercentage(0.45);
    dimensionInfos.append(dimensionInfo);
    dimensionInfo.setText("维度5");
    dimensionInfo.setPercentage(0.65);
    dimensionInfos.append(dimensionInfo);
    pDimensionChartWidget->setDimensionInfos(dimensionInfos);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/170659
推荐阅读
相关标签
  

闽ICP备14008679号