Bienvenue sur le forum !

Si vous souhaitez rejoindre la communauté, cliquez sur l'un de ces boutons !

Qt 5 : 5.9.1 - Qt Creator : 4.4.0 - Qt Installer : 2.0.3 - JOM : 1.1.2 - Qt Build suite : 1.7.0 - VS Qt 5 : 2.0.0

Limiter le déplacement d'un QGraphicsItem

Bonjour!

Je réalise une petite IHM à base de QGrahicsView, QGraphicsScene et QGraphicsItem
J'ai 2 types de QGraphicsItem: un rectangle qui définit une zone précise sur une image, et un capteur.
Le capteur est un genre de caméra, représenté par un triange. La base du triangle, c'est l'emplacement de la caméra, le cône, c'est son champ de vision.

L'utilisateur peut placer à volonté des capteurs dans la zone. Il peut les déplacer, les tourner, les agrandir, en ajouter, en supprimer, tout à la souris.
Sa seule restriction, c'est que la base du capteur doit être dans la zone. Le cône de champ de vision peut se trouver à l'extérieur de la zone, mais la base doit impérativement être dans la zone.

D'un point de vue ergonomie, je souhaite que lorsqu'il déplace son capteur à la souris et que la base du capteur atteint les limites de la zone, alors le capteur reste en butée. Mieux encore (pas encore implémenté dans le futur bout de code), si le capteur entre en butée, mais que l'utilisateur maintient le clic et tourne autour de la zone, alors le capteur se rapproche le plus possible de la souris, mais toujours en restant dans sa zone (il se déplace sur le contour en fait).

Sauf que ce comportement, je n'arrive pas à le réaliser. J'ai activé QGraphicsItem::ItemIsMovable, et voici mon mouseMoveEvent:

void Sensor::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
if(activeZone.contains(scenePos())) //la base du capteur est dans la zone, OK
{
lastValidPosition = scenePos();
}
else //Pas dans la zone, NOK
{
event->ignore(); //refuse l'evenement
setPos(lastValidPosition); // !!! pas déplacé immédiatement
}
QGraphicsItem::mouseMoveEvent(event); //obligatoire pour pouvoir déplacer Capteur
}
Ici, le setPos ne déplace pas immédiatement l'item. Le capteur suit toujours la souris. C'est au prochain mouseMoveEvent qu'il va prendre comme point de départ lastValidPosition. Je ne trouve pas de solution pour qu'il arrête de suivre la souris et reste emprisonné dans la zone!

Comment vous vous y prendriez?

Merci!

Arnaud

Réponses

  • Ok, c'était pas grand chose, voici la modif:

    void Sensor::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
    {
    QGraphicsItem::mouseMoveEvent(event); //D'ABORD réaliser le déplacement
    if(activeZone.contains(scenePos())) //la base du capteur est dans la zone, OK
    {
    lastValidPosition = scenePos();
    }
    else //Pas dans la zone, NOK
    {
    // event->ignore(); //pas necessaire
    setPos(lastValidPosition); //puis restaurer une position valide
    }
    }
    Avec ça, le capteur se fige sur les bords de la zone.
    Maintenant la deuxième étape: le capteur suit la souris en restant enfermé dans la zone.
    Je me suis très vite aperçu d'une difficulté: si l'utilisateur effectue une rotation, disons de 90°, alors les X du capteur sont alignés sur les Y de la souris! Ca va se corser!
  • Hello,

    À mon avis, il faut que tu gères X et Y séparément, chacun avec ses valeurs min & max.
    Comme ça si tu arrives en butée en X max par ex., X prend la valeur max, mais ça n'empêche pas de bouger en Y pour suivre la souris.

    En cas de rotation ou de redimensionnement, il faut vérifier les min/max et bouger l'objet en conséquence.
Connectez-vous ou Inscrivez-vous pour répondre.