Qt 5绘图translate、rotate及字体填充问题的修复方案咨询
QGeoView QGVAirplane 绘制问题解决方案
1. 解决旋转平移后包围盒不覆盖、中心不对准问题
核心思路
projShape必须基于旋转后完整的绘制路径计算包围盒,同时绘制时通过坐标系变换确保中心锚点精准对齐。
具体实现步骤
- 重写onProjection():提前计算以
mProjPoint为中心的旋转后完整路径,保存为成员变量:
void QGVAirplane::onProjection(QGVMap* map) { QGVDrawItem::onProjection(map); // 创建以(0,0)为中心的本地飞机形状路径(替换为你的实际形状) QPainterPath localPath; localPath.moveTo(0, -20); localPath.lineTo(-10, 15); localPath.lineTo(0, 10); localPath.lineTo(10, 15); localPath.closeSubpath(); // 应用旋转+平移到投影点 QTransform transform; transform.translate(mProjPoint.x(), mProjPoint.y()); transform.rotate(mAirplaneHeading); // 你的飞机朝向角度 mProjPath = transform.map(localPath); }
- 重写projShape():直接返回旋转后路径的包围盒,确保完全覆盖绘制内容:
QPainterPath QGVAirplane::projShape() const { QPainterPath shape; shape.addRect(mProjPath.boundingRect()); return shape; }
- 重写projPaint():通过坐标系变换避免手动偏移,确保中心对齐:
void QGVAirplane::projPaint(QPainter* painter) { painter->save(); // 先平移到投影点,再旋转,保证旋转中心是mProjPoint painter->translate(mProjPoint); painter->rotate(mAirplaneHeading); // 绘制以(0,0)为中心的本地路径 painter->setBrush(mAirplaneBrush); painter->setPen(mAirplanePen); QPainterPath localPath; localPath.moveTo(0, -20); localPath.lineTo(-10, 15); localPath.lineTo(0, 10); localPath.lineTo(10, 15); localPath.closeSubpath(); painter->drawPath(localPath); painter->restore(); // 后续绘制编号标签(见下一部分) }
2. 解决编号标签非实心填充问题
核心思路
标签的填充需独立设置实心画刷,不能复用飞机的画刷,确保背景为实心纯色。
具体实现
在projPaint()中单独处理标签绘制:
// 接上述projPaint代码,绘制编号标签 painter->save(); // 计算标签位置:飞机中心下方30像素(可按需调整) QPointF labelPos = mProjPoint + QPointF(0, 30); // 设置实心背景画刷 QBrush labelBgBrush(Qt::white); // 替换为你需要的背景色 QPen labelPen(Qt::black); // 标签文字/边框颜色 // 绘制标签背景矩形(先画背景再画文字) QFont labelFont = painter->font(); labelFont.setPointSize(10); painter->setFont(labelFont); QRectF labelRect = painter->boundingRect(labelPos, Qt::AlignCenter, mPlaneNumber); labelRect.adjust(-5, -3, 5, 3); // 增加边距优化显示 painter->setBrush(labelBgBrush); painter->setPen(labelPen); painter->drawRect(labelRect); // 绘制标签文字 painter->setBrush(Qt::NoBrush); painter->drawText(labelRect, Qt::AlignCenter, mPlaneNumber); painter->restore();
关键注意点
- 绘制顺序必须是先背景矩形,后文字,避免文字被背景覆盖。
- 必须单独创建
QBrush(Qt::SolidPattern, 目标颜色),不能直接使用飞机的画刷。
内容的提问来源于stack exchange,提问作者weirdgyn
相关产品推荐
相关产品推荐

