Qt绘图场景中如何实现自定义箭头多边形45度旋转
问题描述
Qt绘图开发中,需要向QGraphicsScene场景添加旋转45度的箭头形状多边形。目前已经定义好箭头对应的QPolygonF顶点坐标,完成了多边形平移定位,但无法实现正确的旋转变换。
现有实现代码如下:
QBrush greenBrush (Qt::green); QPolygonF poly; poly << QPoint(0,45); poly << QPoint(60,45); poly << QPoint(60,35); poly << QPoint(100,50); poly << QPoint(60,65); poly << QPoint(60,55); poly << QPoint(0,55); poly << QPoint(0,45); poly.translate(130,130); scene->addPolygon(poly,blackPen,greenBrush);
实现方案
旋转变换的核心坑点:直接对平移后的多边形执行旋转,默认会围绕场景坐标原点(0,0)计算变换,会导致箭头旋转后整体偏移到非预期位置。
推荐使用Qt Graphics View框架自带的图形项变换能力实现,不需要手动计算多边形顶点变换,逻辑更简单,后续动态调整角度、位置也更灵活。
实现步骤
- 定义多边形顶点时统一使用
QPointF类型代替QPoint,避免整数坐标变换时的精度损失 - 添加多边形到场景后拿到
QGraphicsPolygonItem实例,通过setPos()设置图形项位置,替代手动对多边形做translate操作 - 调用
setTransformOriginPoint()指定旋转中心为箭头自身的几何中心:该箭头的几何中心为本地坐标下的(50,50)点,刚好位于箭杆中轴位置,绕该点旋转不会出现位置偏移 - 调用
setRotation()传入45即可完成顺时针45度旋转(Qt默认坐标系y轴向下,正角度对应顺时针旋转),需要逆时针旋转时传入-45即可
修正后完整代码
// 补全原有代码缺失的画笔定义 QPen blackPen(Qt::black); QBrush greenBrush(Qt::green); QPolygonF poly; poly << QPointF(0,45); poly << QPointF(60,45); poly << QPointF(60,35); poly << QPointF(100,50); poly << QPointF(60,65); poly << QPointF(60,55); poly << QPointF(0,55); poly << QPointF(0,45); // 添加多边形到场景,不提前对多边形做平移变换 QGraphicsPolygonItem* arrowItem = scene->addPolygon(poly, blackPen, greenBrush); // 设置箭头在场景中的定位,等价于原有平移逻辑 arrowItem->setPos(130, 130); // 以箭头自身几何中心为旋转原点 arrowItem->setTransformOriginPoint(50, 50); // 顺时针旋转45度 arrowItem->setRotation(45);
可选方案:直接计算多边形几何变换
如果不需要动态调整箭头属性,也可以通过QTransform直接计算旋转后的多边形顶点,注意变换顺序要保证旋转围绕多边形自身中心执行:
QPen blackPen(Qt::black); QBrush greenBrush(Qt::green); QPolygonF poly; poly << QPointF(0,45); poly << QPointF(60,45); poly << QPointF(60,35); poly << QPointF(100,50); poly << QPointF(60,65); poly << QPointF(60,55); poly << QPointF(0,55); poly << QPointF(0,45); QTransform transform; // 最后执行:平移到目标位置 transform.translate(130, 130); // 第二步执行:45度旋转 transform.rotate(45); // 最先执行:将多边形中心偏移到坐标原点,避免旋转时位置偏移 transform.translate(-50, -50); // 应用所有变换得到最终多边形 poly = transform.map(poly); scene->addPolygon(poly, blackPen, greenBrush);
注意:
QTransform的变换执行顺序和代码调用顺序相反,最后调用的变换会最先执行,书写时需要注意顺序。
内容的提问来源于stack exchange,提问作者Tarik Subasic
相关产品推荐
相关产品推荐

