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

QGraphicsRectItem实现按住鼠标移动时方块涂黑的方案咨询

嘿,你的需求其实很好实现,我看了你现有的代码,思路方向是对的,只是在Qt事件机制的细节上没处理到位。下面给你两种靠谱的解决方案,你可以根据自己的喜好选:

解决思路:按住左键拖动时让经过的方块变黑

方案一:优化现有Hover事件实现

你用hoverEnterEvent配合鼠标按键判断的思路没问题,但缺了一个关键设置——给视图开启鼠标跟踪,另外可以稍微调整事件逻辑让它更可靠。

  1. 先在main.cpp里给QGraphicsView加上鼠标跟踪:
view->setMouseTracking(true);

默认情况下,QGraphicsView只有在鼠标按下时才会跟踪鼠标移动,开了这个属性后,不管按没按鼠标,hover事件都能正常触发。

  1. 然后微调Square类的hoverEnterEvent:
void Square::hoverEnterEvent(QGraphicsSceneHoverEvent *event) {
    // 先调用父类的事件处理,避免影响其他默认行为
    QGraphicsRectItem::hoverEnterEvent(event);
    // 检查左键是否按住,同时当前方块还不是黑色
    if (QApplication::mouseButtons() & Qt::LeftButton && brush().color() != Qt::black) {
        setBrush(Qt::black);
        // 这里update()其实可以不用,setBrush会自动触发重绘
    }
}

这样改完后,你按住左键移动鼠标,经过的方块就会一个个变黑了。

方案二:在场景层面处理鼠标移动事件

要是hover事件偶尔出现漏触发的情况,你可以换个思路——直接在自定义场景里监听鼠标移动,实时检测鼠标底下的方块并变色,这种方式稳定性更高。

  1. 先写一个自定义的QGraphicsScene子类:
// customscene.h
#ifndef CUSTOMSCENE_H
#define CUSTOMSCENE_H
#include <QGraphicsScene>

class CustomScene : public QGraphicsScene {
    Q_OBJECT
protected:
    void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
};
#endif // CUSTOMSCENE_H
// customscene.cpp
#include "customscene.h"
#include "square.h"
#include <QGraphicsSceneMouseEvent>

void CustomScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event) {
    // 先调用父类方法,保证场景的其他功能正常
    QGraphicsScene::mouseMoveEvent(event);
    // 检查左键是否处于按下状态
    if (event->buttons() & Qt::LeftButton) {
        // 获取鼠标当前位置下的所有item
        QList<QGraphicsItem*> itemsUnderMouse = items(event->scenePos());
        for (QGraphicsItem* item : itemsUnderMouse) {
            // 把item转换成Square类型
            Square* square = qgraphicsitem_cast<Square*>(item);
            if (square && square->brush().color() != Qt::black) {
                square->setBrush(Qt::black);
            }
        }
    }
}
  1. 最后在main.cpp里把原来的QGraphicsScene换成这个自定义的:
CustomScene * scene = new CustomScene(0,0,200,250);

小提醒

  • 别给方块设置setFlag(QGraphicsItem::ItemIsMovable),不然按住左键时方块会被拖动,打乱你的变色操作。
  • 如果方块有重叠,方案二里的items()会返回所有重叠的item,你可以根据需要改成只取最顶层的(比如用itemAt()代替items())。

内容的提问来源于stack exchange,提问作者poor_fool_mloo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:35:18