Bonjour les gars j'ai besoin de votre aide,gigue de collision QGraphicsItem/trembler
Je crée une ligne de temps comme widget dans Qt basé sur le cadre QGraphics. Mon problème est de gérer les collisions d'éléments (hérités de QGraphicsRectItem) dans mes pistes Timeline. J'utilise la fonction itemChange() pour suivre les collisions. Pour conserver les éléments dans le boundingRect parent j'utilise le wich code suivant fonctionne comme un charme
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;
}
}
Cela arrête immédiatement les articles si elles atteignent la limite gauche ou à droite de mes pistes timline, même si je déplace la souris à l'extérieur ma vue/scène. C'est comme un mur invisible. Maintenant, je veux le même comportement si un élément d'une piste entre en collision avec un autre.
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;
}
Le problème est que si je me déplace un élément via la souris contre un autre élément que vous voyez intersection/chevauchement, puis l'élément je me suis déplacé en arrière à boutons-pression la distance minimale ne recoupant pas. Comment puis-je arrêter l'objet en mouvement immédiatement s'il en touche un autre (pas de mouvement qui s'entrecroise). Tout comme la façon dont les éléments sont conservés chez les parents boundingRect (premier bloc de code), le mur invisible comme le comportement?
Merci pour votre réponse, bon point mais cela n'a pas résolu le problème. – RobRobRob
L'un de ces éléments est-il parent? Si tel est le cas, vous disposez d'un mélange de systèmes de coordonnées, c'est-à-dire que "newPos" et "offset" sont dans les coordonnées parentes, mais "thisRect" et "collideRect" sont dans les coordonnées de la scène. Si elles ne sont pas parentales, alors ce sont toutes les coordonnées de la scène, et dans ce cas, je pense que cela semble correct. Si des éléments parents sont concernés, utilisez mapToScene au lieu de mapToParent, puis mappez newPos aux coordonnées de scène pour toutes les comparaisons et ajustements, puis revenez aux coordonnées parent avant de les renvoyer. – goug
Les éléments sont parentés à un élément de piste, mais il a la même largeur que la scène et son rect est également défini sur (0,0). Donc, l'origine x, y devrait être la même. – RobRobRob