如何通过mouseMoveEvent实现QGraphicsPixmapItem绕指定点随鼠标位置旋转
问题修正方案
你代码的偏移和旋转异常来自三个核心逻辑错误:
- 角度计算完全不符合需求:你需要计算的是鼠标位置相对于指定旋转中心点的向量夹角,现有两个atan2值相减的逻辑没有任何数学依据,且
atan2返回弧度值,setRotation要求输入角度值,缺少单位转换 setTransformOriginPoint接收的是QGraphicsPixmapItem自身局部坐标系的坐标,你传入的是场景坐标差值,坐标系不匹配直接导致绘制偏移setMouseTracking(true)不需要每次鼠标移动都重复设置,放在构造函数初始化阶段即可
修正后的代码如下:
// 初始化阶段(比如Game构造函数里)提前设置鼠标追踪,不用放在mouseMoveEvent里 Game::Game() { // ... 其他初始化逻辑 setMouseTracking(true); } void Game::mouseMoveEvent(QMouseEvent* e){ // 1. 定义场景级的旋转锚点:场景顶部中点 QPoint midPos(sceneRect().width() / 2, 0); // 2. 把鼠标坐标转成场景坐标 QPointF currPos = mapToScene(e->pos()); // 3. 计算鼠标相对于旋转锚点的向量 QPointF diff = currPos - midPos; // 4. 计算角度:atan2返回弧度,转成角度,可根据素材初始朝向加固定偏移值调整对准精度 double angle = qRadiansToDegrees(atan2(diff.y(), diff.x())); // 5. 把场景级的旋转锚点转成cannon自身的局部坐标,设置为变换原点 cannon->setTransformOriginPoint(cannon->mapFromScene(midPos)); // 6. 应用旋转 cannon->setRotation(angle); }
如果大炮指向和鼠标位置存在固定角度差,只需要根据你的素材初始朝向给angle加固定偏移值(比如±90°)即可完全对齐。
内容的提问来源于stack exchange,提问作者Achille
相关产品推荐
相关产品推荐

