Modèle

 

Trois fichiers sont nécessaires dans ce modèle

main.cpp

#include <QApplication>

#include "fenetre.h"

int main (int argc, char *argv []) {
     QApplication app (argc, argv);
     Fenetre f;
     f.show();
     return app.exec ();
}

On construit l'application puis la fenêtre qu'on rend visible (f.show();) avant de lancer la boucle d'exécution.

fenetre.h

#ifndef FENETRE_H
#define FENETRE_H

#include <QtGui>
#include "geo2D/....h"
#include "geo2D/....h"
...
//#include "geo2D/geo2D.h"

On intègre la bibliothèque Qt puis la bibliothèque geo2D complète (#include "geo2D/geo2D.h") ou uniquement les objets graphiques utiles.

class Fenetre: public QWidget {

    Q_OBJECT                                                             // macro indispensable pour la gestion des mouvements de la souris

public:
    repere *R;
    point_libre *A, *B,...                                              // on déclare ici les pointeurs sur les objets géométriques
...

    bool presse;                                                          // utilisé pour signaler un déplacement en cours
    bool debut;

    Fenetre (QWidget *parent = 0);                              // constructeur de la fenêtre

protected:
    void paintEvent (QPaintEvent *);                             // appelé lorsque le tracé de la fenêtre et de son contenu est requis
    void mousePressEvent(QMouseEvent *event);          // appelé lorsqu'on appuie sur le bouton gauche de la souris
    void mouseMoveEvent(QMouseEvent *event);          // appelé lorsqu'on déplace la souris
    void mouseReleaseEvent(QMouseEvent *event);       // appelé lorsqu'on relache le bouton de la souris 

};

#endif

 

fenetre.cpp

#include "fenetre.h"

Fenetre::Fenetre (QWidget *parent): QWidget (parent) {
    setGeometry (...);                                                   // on fixe les dimensions de la fenêtre
    setMouseTracking (true);                                         // pour gérer tous les déplacements de la souris (bouton pressé ou non)
    setCursor (Qt::ArrowCursor);                                  // on fixe le curseur
    presse = false;                                                       // on initialise l'indicateur de dépacement
    debut = true;

    R = new repere (...);                                               // on construit ici tous les objets géométriques
    A = point_libre (...);
    B = point_libre (...);
...
 }

void Fenetre::paintEvent (QPaintEvent *) {                    // tracé de la fenêtre
    if (debut) {                                                             // on "peint" la fenêtre en blanc la première fois
        debut = false;
        setPalette (QPalette (QColor (255, 255, 255)));
        setAutoFillBackground (true);
    }

    QPainter painter (this);                                            // on trace le repère et tous les objets géométriques
    painter.setPen (Qt::red);
    (*R).trace (&painter);
...
    (*A).trace (&painter);                                              // on peut aussi écrire A->trace (&painter);
    (*B).trace (&painter);
...
}

 

void Fenetre::mousePressEvent (QMouseEvent *event) {
    int X = event -> x ();
    int Y = event -> y ();
    presse = (*A).select (X, Y) || (*B).select (X, Y) || ...; 
    if (presse)
        setCursor (Qt::ClosedHandCursor);
}

Méthode appelée chaque fois que l'on presse le bouton gauche de la souris. On teste si on est proche des points déplaçables (point libre, point sur droite, point sur cercle, curseur), si oui on positionne l'indicateur deplace de l'objet et l'indicateur presse puis on change le curseur pour indiquer un déplacement en cours.

void Fenetre::mouseMoveEvent (QMouseEvent *event) {
    int X = event -> x ();
    int Y = event -> y ();
    if (presse) {
        (*A).bouge (X, Y);
        (*B).bouge (X, Y);
...
        update ();

Méthode appelée lorsqu'on déplace la souris. Si un déplacement est en cours, on bouge l'objet dont l'indicateur deplace contient la valeur true, on recalcule éventuellement les objets dépendants (droite (AB) par exemple) puis on relance le tracé : fonction update();.

    } else {
        bool proche = (*A).zone (X, Y) || (*B).zone (X, Y);
        if (proche)
            setCursor (Qt::PointingHandCursor);
        else
            setCursor (Qt::ArrowCursor);
    }
}

S'il n'y a pas de déplacement en cours on change juste le curseur si on est proche d'un objet déplaçable.

void Fenetre::mouseReleaseEvent (QMouseEvent *) {
    (*A).stop();
    (*B).stop();
...
    presse = false;
    setCursor (Qt::PointingHandCursor);
}

Si le bouton de la souris est relachée on remet la valeur false dans tous les indicateurs de déplacement et on change le curseur.