You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何同时使用QGraphicsScene的MouseMoveEvent与QGraphicsItem的Hover事件?

解决QGraphicsScene鼠标移动事件与Item悬停事件冲突的问题

我之前也碰到过一模一样的问题,其实核心原因很直白:当你重写QGraphicsScene的mouseMoveEvent却没有调用父类的实现时,Qt的事件传递链被打断了——而Item的hover事件(hoverEnterEvent/hoverLeaveEvent)完全依赖场景把鼠标移动事件分发给对应的Item,所以才会失效。

解决方案:在场景的事件处理函数中调用父类实现

你只需要在GraphicsScene的mouseMoveEvent和mousePressEvent末尾,加上父类的事件处理调用,就能让hover事件恢复正常,同时完全不影响你绘制临时线条的逻辑。

修改后的mouseMoveEvent代码:

void GraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { 
    if(lineActivated){ 
        const QPointF pos = event->scenePos(); 
        tempLine.setP2(pos); 
        update(); // 别忘了调用update()让场景重绘临时线条,不然看不到实时变化
    }
    // 关键:让父类处理剩余的事件逻辑,包括hover事件的分发
    QGraphicsScene::mouseMoveEvent(event);
}

修改后的mousePressEvent代码:

void GraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) { 
    for (int i = 0; i < pointList.size(); ++i) { 
        if (pointList[i]->over == 1){ 
            pointList[i]->press(); 
            lineActivated=true; 
            tempLine.setLine(pointList[i]->x(),pointList[i]->y(),pointList[i]->x(),pointList[i]->y()); 
        } 
    }
    // 调用父类处理,确保其他Item的点击事件也能正常响应
    QGraphicsScene::mousePressEvent(mouseEvent);
}

原理说明

Qt的事件系统是链式传递的:场景会先处理自身的事件,然后把未处理的事件分发给对应的Item。如果你重写了场景的事件函数却不调用父类,就相当于告诉Qt“这个事件我已经处理完了,不用往下传了”,Item自然收不到hover相关的事件通知。

另外补充个小细节:如果你的tempLine是QGraphicsLineItem,记得要把它添加到场景中(比如addItem(&tempLine)),否则即使修改了坐标也不会显示出来。

内容的提问来源于stack exchange,提问作者Théo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 14:32:34