QT实现自定义多边形维度图
立即下载
资源介绍:
QT自定义维度图,本示例实现六边形战力统计维度图,一种将六个维度的战力统计以六边形图形展示的方法。六个维度是:攻击力、防御力、速度、智力、生命值、特殊能力。六边形战力统计维度图将这些维度以六个边长不等的六边形表示,每个边长代表对应维度的数值大小。通过连接这些边,可以得到一个多边形,多边形的形状和大小表示单位的整体战斗能力。
#include "DimensionChartWidget.h"
#include
#include
#include
DimensionChartWidget::DimensionChartWidget(QWidget *parent) : QWidget(parent)
{
m_radius = 0;
m_sidesNumber = 1;
init();
}
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 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);
}
//绘制文本
void DimensionChartWidget::drawText(QPainter& painter, QPointF point, QString text)
{
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.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);
}
void DimensionChartWidget::convertPoint(QPointF& point)
{
if(qAbs(point.x()) < 0.001)
{
point.setX(0);
}
else if(qAbs(point.y()) < 0.001)
{
point.setY(0);
}
}
void DimensionChartWidget::init()
{
setBackgroundColor(QColor(255,255,255));
// 设置维度网格数量
setSidesNumber(5);
// 设置维度半径
setRadius(120);
// 设置维度网格画笔
QPen sidesPen;
sidesPen.setColor(QColor("#0095C5"));
sidesPen.setWidth(2);
setSidesPen(sidesPen);
// 设置维度画笔
QPen dimensionPen;
dimensionPen.setColor(Qt::GlobalColor::red);
dimensionPen.setWidth(3);
setDimensionPen(dimensionPen);
// 设置字体信息
QPen textPen;
setTextPen(textPen);
QFont textFont;
textFont.setFamily("微软雅黑");
textFont.setPointSize(10);
setTextFont(textFont);
}