2016-11-07 1 views
0

안녕 얘들 아,QGraphicsItem 충돌 지터/나는 당신의 도움이 필요

나는 QGraphics와 Graphics 프레임 워크를 기반으로 Qt는의 위젯과 같은 타임 라인을 만드는거야을 떨다. 내 문제는 내 타임 라인 트랙에서 (QGraphicsRectItem에서 상속 된) 항목의 충돌을 처리하는 것입니다.

itemChange() 함수를 사용하여 충돌을 추적합니다. 나는 다음과 같은 코드 느릅 나무를 사용하는 부모 boundingRect의 항목을 유지하는 것은 내가 외부 마우스를 이동하는 경우에도, 그들은 내 timline 트랙의 왼쪽 또는 오른쪽 경계에 도달하면

if (change == ItemPositionChange && scene()) 
    if (thisRect.intersects(parentRect)) { 
     const QPointF offset(mapFromParent(thisRect.topLeft())); 
     QPointF newPos(value.toPointF()); 

     if (snapToGrid) { 
      newPos.setX(floor(qMin(parentRect.right() - offset.x() - thisRect.width(), 
            qMax(newPos.x(), parentRect.left()/2 - offset.x()))/(snapValue * pxPerSec(duration))) * snapValue * pxPerSec(duration)); 
     } 
     else {    
      newPos.setX(qMin(parentRect.right() - offset.x() - thisRect.width(), 
          qMax(newPos.x(), parentRect.left() - offset.x()))); 
     } 

     newPos.setY(parentItem()->boundingRect().height() * 0.1); 
     return newPos; 
    } 
} 

이 즉시 항목을 중지 매력처럼 작동 내보기/장면. 그것은 보이지 않는 벽과 같습니다. 트랙의 한 항목이 다른 항목과 충돌하면 동일한 동작이 필요합니다.

const QRectF parentRect(parentItem()->sceneBoundingRect()); 
const QRectF thisRect(sceneBoundingRect()); 

    foreach (QGraphicsItem *qgitem, collidingItems()) { 
     TimelineItem *item = qgraphicsitem_cast<TimelineItem *>(qgitem); 
     QPointF newPos(value.toPointF()); 

     if (item) { 
      const QRectF collideRect = item->sceneBoundingRect(); 
      const QPointF offset(mapFromParent(thisRect.topLeft())); 

      if (thisRect.intersects(collideRect) && thisRect.x() < collideRect.x()) { 
       newPos.setX(collideRect.left() - offset.x() - thisRect.width()); 
      } 

      if (thisRect.intersects(collideRect) && thisRect.x() > collideRect.x()) { 
       newPos.setX(collideRect.right() + offset.x()); 
      } 

     } 

     newPos.setY(parentItem()->boundingRect().height() * 0.1); 
     return newPos; 
    } 

문제는 그 다음 다른 당신이 그 (것)들을 교차 참조 항목/겹침에 마우스를 통해 항목을 항목을 이동하면 내가 거리를 교차하지 최소로 다시 스냅을 이동한다는 것입니다. 움직이는 물건이 다른 물건을 치면 즉각 멈출 수있는 방법 (떨림이없는 뒤로 움직이는 물건을 교차시키지 말 것). 항목이 부모 boundingRect (첫 번째 코드 블록)에 보관되는 것과 마찬가지로 보이지 않는 벽은 동작과 유사합니까?

답변

0

여기서 문제는 "thisRect"라고 생각합니다. ItemPositionChange에서 this를 호출하면 sceneBoundingRect는 항목의 경계 사각형을 새 위치가 아닌 이전 위치로 반환합니다. 충돌이 발생하더라도 현재 위치가 성공하지만 다음 결과는 항상 이전 결과를 확인한 후 다시 충돌하여 충돌을 피하기 때문에 실패합니다. 나는 그래서 루프 밖에서 "new_pos"의 생성을 이동 한

QPointF new_pos (value.toPointF()); 
QRectF thisRect (sceneBoundingRect()); 
thisRect.translate (new_pos - pos()); 

:

로컬 항목의 장면 사각형을 받고 후에는 항목의 새로운 미래 위치로 변환해야합니다 사각형 변환에 사용할 수 있습니다. 또한 더 빠릅니다.

+0

답장을 보내 주셔서 감사합니다. 문제는 해결되지 않았습니다. – RobRobRob

+0

이러한 항목 중 상위 항목에 상위 항목이 있습니까? 그렇다면 "newPos"와 "offset"이 상위 좌표이지만 'thisRect'와 'collideRect'가 장면 좌표에 있습니다. 부모가 아닌 경우 장면 좌표가 모두 표시됩니다.이 경우 올바른 것으로 보입니다. 상위 항목이있는 경우 mapToParent 대신 mapToScene을 사용하고 newPos를 모든 비교 및 ​​조정을위한 장면 좌표로 매핑 한 다음 반환하기 전에 부모 좌표로 돌아갑니다. – goug

+0

항목은 트랙 항목에 적용되지만 장면과 너비는 같으며 rect도 (0,0)으로 설정됩니다. 따라서 x, y 원점은 동일해야합니다. – RobRobRob

관련 문제