赞
踩
一、效果展示
二、头文件
#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
三、源文件
#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); } }
四、调用示例
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); }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。