#include <QtWidgets>
const int kMargin = 30;
const int kRadius = 100;
class PolarWidget : public QWidget {
Q_OBJECT
public:
PolarWidget(QWidget* parent = nullptr)
: QWidget(parent)
, m_data(10, 0)
{
setMinimumSize(2 * kMargin + 2 * kRadius, 2 * kMargin + 2 * kRadius);
setBackgroundRole(QPalette::Base);
setAutoFillBackground(true);
}
void setData(const QVector<double>& data) {
m_data = data;
update();
}
QVector<double> data() const {
return m_data;
}
protected:
void paintEvent(QPaintEvent* event) override {
Q_UNUSED(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
// 绘制坐标系
drawCoordinateSystem(painter);
// 绘制雷达图
drawRadarChart(painter);
}
private:
void drawCoordinateSystem(QPainter& painter) {
painter.setPen(QPen(Qt::black, 1.5));
// 绘制圆
QRectF rect(kMargin, kMargin, 2 * kRadius, 2 * kRadius);
painter.drawEllipse(rect);
// 绘制半径线和标签
for (int i = 0; i < m_data.size(); ++i) {
double angle = 2 * M_PI / m_data.size() * i;
QPointF p1(kMargin + kRadius, kMargin + kRadius);
QPointF p2(p1.x() + kRadius * cos(angle), p1.y() + kRadius * sin(angle));
painter.drawLine(p1, p2);
QString label = QString::number(m_data[i]);
QFontMetrics fm(QFont());
QPointF textP(p2.x() - fm.width(label) / 2.0, p2.y() - fm.height() / 2.0);
painter.drawText(textP, label);
}
}
void drawRadarChart(QPainter& painter) {
painter.setPen(QPen(Qt::blue, 2));
QVector<QPointF> points;
for (int i = 0; i < m_data.size(); ++i) {
double angle = 2 * M_PI / m_data.size() * i;
double r = m_data[i] / 100 * kRadius;
QPointF p(kMargin + kRadius + r * cos(angle), kMargin + kRadius + r * sin(angle));
points.append(p);
}
// 绘制雷达图
painter.drawPolygon(QPolygonF(points));
}
private:
QVector<double> m_data;
};
该示例控件可以通过 setData() 方法设置需要显示的极角数据,数据以 QVector<double> 的形式传入。
在控件内部会绘制出对应的极坐标系和雷达图,其中极坐标系包括圆、半径线和标签等元素,雷达图则是根据数据进行连线绘制而成。