QGraphicsItem碰撞抖动/颤抖



大家好,我需要你们的帮助,

我正在创建一个像Qt基于QGraphics框架小部件的时间轴。我的问题是处理项目的碰撞(从qgraphicsrectem继承)在我的时间轴轨道。

我使用itemChange()函数跟踪冲突。为了将项保留在父boundingRect中,我使用以下代码,其工作原理类似于charm

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

问题是,如果我通过鼠标移动一个项目对另一个项目,你会看到它们相交/重叠,然后我移动的项目snaps回到最小不相交的距离。我如何设法停止立即移动的项目,如果它击中另一个(没有颤抖来回运动相交的东西)。就像项目保存在父母boundingRect(第一个代码块)的方式,无形的墙一样的行为?

我认为这里的问题是与"thisRect"。如果你从ItemPositionChange调用这个,那么sceneBoundingRect将返回项目在其前一个位置的边界矩形,而不是新的。发生的情况是,即使存在碰撞,当前位置也会成功,但下一个位置会失败,因为你总是在检查之前的结果,然后它会快速返回以避免碰撞。

获得本地物品的场景矩形后,您需要将其转换为物品的新未来位置:

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

我已经将"new_pos"的创建移到了循环之外,这样它就可以用于矩形的转换。

最新更新