【发布时间】:2016-11-07 09:33:09
【问题描述】:
大家好,我需要你们的帮助,
我正在基于 QGraphics 框架在 Qt 中创建类似小部件的时间线。我的问题是在我的时间轴轨道中处理项目(继承自 QGraphicsRectItem)的冲突。
我使用 itemChange() 函数来跟踪碰撞。为了将项目保留在父 boundingRect 我使用下面的代码就像一个魅力
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(第一个代码块)中的方式一样,隐形墙的行为?
【问题讨论】:
标签: c++ qt collision qgraphicsitem