QGraphicsScene mouseMoveEvent 在 QGraphicsView wheelEvent 之前不起作用

QGraphicsScene mouseMoveEvent does not work until QGraphicsView wheelEvent

我有一个奇怪的问题,我一直无法确定原因。基本上,我创建了一个具有平移和缩放功能的 2D 视图,以及一个包含可以通过网格捕捉移动的项目的场景。为了在场景中移动一个项目,我扩展了 Scene::mousePressEvent 以获取指向该项目的指针,并扩展了 Scene::mouseMoveEvent 以保持项目在光标上的跟踪。为了放下物品,我再次使用了 Scene::mousePressEvent。为了平移,我扩展了 View::mousePressEventView::mouseReleaseEventView::mouseMoveEvent,为了缩放,我扩展了 View::wheelEvent.

现在针对症状:

我用场景中的一个项目启动应用程序。如果我单击并按住,然后移动鼠标,该项目将按预期移动。一旦我松开鼠标按钮,该项目就会停止移动。我可以点击掉落,物品根据Scene::mousePressEvent中的掉落码放置。再试一次,项目仍然只在按下鼠标按钮时移动。

然后是奇怪的部分:如果我使用鼠标滚轮缩放视图,在该事件之后一切都按预期执行。鼠标点击select一个项目,它随着我移动鼠标而移动,当我再次点击时下降。

所以显而易见的解决方案:

    wheelEvent(new QWheelEvent(QPointF(0,0),0,Qt::NoButton,Qt::NoModifier));

在创建视图时调用,一切正常。它调用扩展的 View::wheelEvent 没有改变视图,甚至在场景创建之前,但之后程序的行为符合预期。

所以我来这里是想看看是否有任何优秀的 Qt 专家可以解释这种奇怪的行为。任何意见或方向表示赞赏。

如果有帮助,这里是 View::wheelEvent 覆盖代码。 tform 是一个 QTransform,我用它来保持缩放。此外,我尝试过调用和不调用基本方法,但行为没有变化。

void SchematicView::wheelEvent(QWheelEvent* event)
{  
    // Scale the view / do the zoom
    double scaleFactor = 1.1;

    if(event->delta() > 0 && tform.m11() < max_zoom) {
        tform.scale(scaleFactor,scaleFactor);
    } else if (event->delta() < 0 && tform.m11() > min_zoom){
        tform.scale(1.0/scaleFactor,1.0/scaleFactor);
    }

    setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
    setTransform(tform);

    QGraphicsView::wheelEvent(event);

}

没有 SSCCE to look at and test with, it's hard to say for sure, but what you're describing sounds a lot like your mouseMoveEvent() callback is only getting called when the mouse button is being held down during the move. That, in turn, sounds a lot like the expected behavior for mouseMoveEvent(), as documented in QWidget::mouseMoveEvent():

If mouse tracking is switched off, mouse move events only occur if a mouse button is pressed while the mouse is being moved. If mouse tracking is switched on, mouse move events occur even if no mouse button is pressed.

如果这确实是问题所在,那么调用 setMouseTracking(true) 可能会让您获得所需的行为。

在更广泛的层面上,请注意有更简单的方法来获取您尝试实现的行为——例如,要允许用户在 QGraphicsScene 中拖放项目,您真正需要做的就是在您希望用户能够拖动的任何 QGraphicsItems 上调用 setFlags(QGraphicsItem::ItemIsMovable)。除非您试图获得一些非标准行为,否则无需对事件处理程序进行手动编码。