2015-10-08 42 views
0

我有一个奇怪的问题,我一直无法确定原因。基本上,我创建了具有平移和缩放功能的2D视图以及可以通过网格对齐移动的项目。要移动场景中的项目,我扩展了Scene::mousePressEvent以获取指向该项目的指针,并且使Scene::mouseMoveEvent获得指示器以跟踪光标上的项目。要删除该项目,我再次使用了Scene::mousePressEvent。为了平移,我扩展了View::mousePressEvent,View::mouseReleaseEventView::mouseMoveEvent并将I扩展为View::wheelEventQGraphicsScene mouseMoveEvent不工作,直到QGraphicsView wheelEvent

现在的症状:

我开始与场景中的项目的应用程序。如果我点击并按住,然后移动鼠标,该项目将按预期移动。只要我释放鼠标按钮,该项目停止移动。我可以点击放下,并根据Scene::mousePressEvent中的下拉代码放置该项目。再试一次,只有当鼠标按钮被按下时,项目才会移动。

然后出现奇怪的部分:如果我使用鼠标滚轮缩放视图,那么在该事件发生后,所有事情都按预期执行。点击鼠标来选择一个项目,它随着我移动鼠标而移动,当我再次点击时,它会掉落。

那么显而易见的解决方案:

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); 

} 
+0

请注意,您的显而易见的解决方案被泄露QWheelEvent对象......你会更好放置QWheelEvent对象在栈上,或wheelEvent()返回后,至少将其删除。 –

回答

2

没有一个SSCCE来看待和测试用,很难肯定地说,但什么你描述听起来很像你mouseMoveEvent()回调才刚刚调用的时候,鼠标按钮在移动过程中被按住。如果 鼠标按钮,而鼠标按下

如果鼠标跟踪已关闭,鼠标移动事件只发生:那反过来,听起来很像的mouseMoveEvent(预期的行为),如记录在QWidget::mouseMoveEvent()正在移动。如果开启了跟踪功能,鼠标移动事件即使没有按下鼠标按钮,也会发生。

如果确实是这个问题,那么致电setMouseTracking(true)可能会得到您正在查找的行为。

在更广泛的层面上,请注意,有更简单的方法可以获得您尝试实施的行为 - 例如,允许用户在QGraphicsScene中拖放项目,您只需调用setFlags(QGraphicsItem :: ItemIsMovable)在您希望用户能够拖动的任何QGraphicsItems上。除非您试图获取一些非标准行为,否则不需要手动编写事件处理程序。

+0

我认为你正在使用setMouseTracking(true)。我明天会尝试。至于场景编码,我需要捕捉到网格,所以我必须处理pressEvent。我很欣赏ItemIsMovable上的建议,但我创建了自己的Item类,它们表示不同的形状和像素图,并且由于我必须重写虚拟绘画事件,所以我没有注意到这些标志做任何事情。如果您有任何关于使用自定义Item类的建议以及可以捕捉到网格的默认可移动行为,我很乐意听到它。没有理由重新发明轮子。没有双关语意。 – Johnny

+0

我相信可以使用标准的item-move功能来处理自定义的QGraphicsItem子类(我自己没有尝试过,但如果它不可能,我会感到惊讶)。至于snap-to-grid,我认为实现这个的方法是重写QGraphicsItem子类中的itemChange(GraphicsItemChange变化,const QVariant&value)方法,并且在(change)等于ItemPositionChange的情况下返回snapped该项目的网格位置。 (请参阅此处的说明:http://doc.qt.io/qt-4.8/qgraphicsitem.html#GraphicsItemChange-enum) –

+0

感谢您解决鼠标跟踪问题。因为在进入这里之前搜索了文档,并且不理解wheelEvent与mouseMove相关的方式,因此我感到很沮丧。 – Johnny

相关问题