QGraphicsRectItem实现按住鼠标移动时方块涂黑的方案咨询
嘿,你的需求其实很好实现,我看了你现有的代码,思路方向是对的,只是在Qt事件机制的细节上没处理到位。下面给你两种靠谱的解决方案,你可以根据自己的喜好选:
解决思路:按住左键拖动时让经过的方块变黑
方案一:优化现有Hover事件实现
你用hoverEnterEvent配合鼠标按键判断的思路没问题,但缺了一个关键设置——给视图开启鼠标跟踪,另外可以稍微调整事件逻辑让它更可靠。
- 先在
main.cpp里给QGraphicsView加上鼠标跟踪:
view->setMouseTracking(true);
默认情况下,QGraphicsView只有在鼠标按下时才会跟踪鼠标移动,开了这个属性后,不管按没按鼠标,hover事件都能正常触发。
- 然后微调
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事件偶尔出现漏触发的情况,你可以换个思路——直接在自定义场景里监听鼠标移动,实时检测鼠标底下的方块并变色,这种方式稳定性更高。
- 先写一个自定义的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); } } } }
- 最后在
main.cpp里把原来的QGraphicsScene换成这个自定义的:
CustomScene * scene = new CustomScene(0,0,200,250);
小提醒
- 别给方块设置
setFlag(QGraphicsItem::ItemIsMovable),不然按住左键时方块会被拖动,打乱你的变色操作。 - 如果方块有重叠,方案二里的
items()会返回所有重叠的item,你可以根据需要改成只取最顶层的(比如用itemAt()代替items())。
内容的提问来源于stack exchange,提问作者poor_fool_mloo
相关产品推荐
相关产品推荐

