Hallo Leute, ich brauche Ihre Hilfe,QGraphicsItem Kollision Jitter/zittern
Ich bin eine Zeitleiste wie Widgets in Qt basiert auf dem QGraphics Rahmen zu schaffen. Mein Problem besteht darin, Kollisionen von Objekten (geerbt von QGraphicsRectItem) in meinen Zeitleistenspuren zu behandeln.
Ich verwende die itemChange() -Funktion, um die Kollisionen zu verfolgen. Um die Elemente in der übergeordneten boundingRect halte ich den folgenden Code Wich verwenden wirkt wie ein Zauber
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;
}
}
Diese Einzelteile sofort stoppt, wenn sie auf den linken oder rechten Rand meiner timline Spuren erreichen, auch wenn ich die Maus außerhalb bewegen meine Sicht/Szene. Es ist wie eine unsichtbare Wand. Jetzt möchte ich das gleiche Verhalten, wenn ein Element in einer Spur mit einer anderen kollidiert.
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;
}
Das Problem ist, dass, wenn ich einen Artikel über Maus gegen ein anderes Element bewegen Sie sie sehen sich schneidende/überlappende und dann den Artikel, den ich zurückschnappt auf das Minimum nicht bewegt Abstand schneidet. Wie schaffe ich es, den bewegenden Gegenstand sofort zu stoppen, wenn er einen anderen Gegenstand berührt (keine zitternde Vor- und Rückwärtsbewegung, die sich kreuzt). Genauso wie die Gegenstände in Elternteilen gehalten werden (erster Codeblock), verhält sich die unsichtbare Wand wie ein Verhalten?
Danke für Ihre Antwort, guter Punkt, aber es hat das Problem nicht gelöst. – RobRobRob
Sind irgendwelche dieser Gegenstände parentered? Wenn ja, dann haben Sie eine Mischung von Koordinatensystemen, d. H. "NewPos" und "offset" sind in übergeordneten Koordinaten, aber "thisRect" und "collideRect" sind in Szene Koordinaten. Wenn sie nicht parented sind, dann sind es alle Szenenkoordinaten, und in diesem Fall denke ich, dass das korrekt aussieht. Wenn es sich um übergeordnete Elemente handelt, verwenden Sie mapToScene anstelle von mapToParent und ordnen Sie dann newPos den Szenenkoordinaten für alle Vergleiche und Anpassungen zu und dann zurück zu den übergeordneten Koordinaten, bevor Sie zurückkehren. – goug
Die Elemente werden einem Spurelement zugewiesen, aber sie haben die gleiche Breite wie die Szene und es ist auch rect (0,0). Also sollte der Ursprung x, y derselbe sein. – RobRobRob