Il s'agit dans cet exemple de créer trois points A, B et C qu'on peut déplacer à l'aide de la souris, de tracer la droite AB, le cercle ABC puis un point M mobile sur la droite (AB) puis enfin un point N mobile sur le cercle passant par A, B, C.

Répertoire : arc. Trois fichiers sont utilisés : main.cpp, fenetre.h et fenetre.cpp.
#include <QApplication>
#include "fenetre.h"
int main (int argc, char *argv []) {
QApplication app (argc, argv);
Fenetre f;
f.show();
return app.exec ();
}
On crée l'application app, le fenêtre principale f puis on lance la boucle d'exécution app.
#ifndef FENETRE_H #define FENETRE_H #include <QWidget> #include <QPaintEvent> #include <QMouseEvent> #include <QPainter> #include "geo2D/point_sur_droite.h" #include "geo2D/point_sur_cercle.h"
On déclare les objets de la bibiliothèque Qt nécessaires. On peut écrire directement #include <QtGui>. Seuls les objets utiles seront annexés. On déclare ensuite les objets de la bibliothèque geo2D nécessaires.On peut écrire directement #include "geo2D/geo2D.h" mais dans ce cas tous les objets de la bibliothèque geo2Dseront ajoutés au programme qui sera donc plus gros.
class Fenetre: public QWidget {
Q_OBJECT
public:
repere *R;
point_libre *A;
point_libre *B;
point_libre *C;
droite *AB;
cercle *ABC;
point_sur_droite *M;
point_sur_cercle *N;
On déclare ici tous les objets géométriques qui seront utilisés.
bool presse;
Indicateur signalant s'il y a un déplacement en cours
Fenetre (QWidget *parent = 0);
protected:
void paintEvent (QPaintEvent *);
void mousePressEvent(QMouseEvent *event);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *event);
};
#endif
On définit ici les quatre fonctions gérant le dessin et l'action de la souris (appui sur le bouton, déplacement, relâchement).
/*
* ptlibre
* teste point sur droite et point sur cercle
*/
#include "fenetre.h"
Fenetre::Fenetre (QWidget *parent): QWidget (parent) {
setGeometry (0, 0, 600, 450);
setMouseTracking (true);
setCursor (Qt::ArrowCursor);
presse = false;
Constructeur de la fenêtre principale : on indique sa taille, on donne la possibilité de gérer le déplacement de la souris sans qu'on ait besoin d'appuyer sur le bouton (setMouseTracking (true);), on fixe le curseur par défaut puis on initialise l'indicateur de déplacement des points libres.
R = new repere (300, 225, 600, 450, 50.0, 50.0, 1.0, 1.0);
A = new point_libre (3.0, 2.0, "A", R);
B = new point_libre (3.0, -2.0, "B", R);
C = new point_libre (0.0, 0.0, "C", R);
AB = new droite (A, B, NULL, R);
ABC = new cercle (A, B, C, NULL, R);
M = new point_sur_droite (AB, "M", R);
N = new point_sur_cercle (ABC, "N", R);
On crée ici les objets géométriques : le repère, les points A, B, C, la droite (AB) puis le cercle passant par A, B et C. On crée ensuite deux autres points M et N. On peut les déplacer mais M appartiendra obligatoirement à la droite AB et N au cercle (ABC).
void Fenetre::paintEvent (QPaintEvent *) {
setPalette (QPalette (QColor (255, 255, 255)));
setAutoFillBackground (true);
QPainter painter (this);
painter.setPen (Qt::red);
(*R).trace (&painter);
painter.setPen (Qt::blue);
A -> trace (&painter);
B -> trace (&painter);
C -> trace (&painter);
AB -> trace (&painter);
ABC -> trace (&painter);
M -> trace (&painter);
N -> trace (&painter);
}
On redessine ici la figure : on peint le fond en blanc, on trace le repère en rouge puis les points la droite et le cercle.
void Fenetre::mousePressEvent (QMouseEvent *event) {
int X = event -> x ();
int Y = event -> y ();
presse = A -> select (X, Y) || B -> select (X, Y) || C -> select (X, Y)
|| M -> select (X, Y) || N -> select (X, Y);
if (presse)
setCursor (Qt::ClosedHandCursor);
}
On teste, dans cet ordre, si la souris est proche de A, B, C, M ou N. Si c'est le cas l'indicateur de déplacement du point est positionné ainsi que le booléen presse. On change ensuite le curseur.
void Fenetre::mouseMoveEvent (QMouseEvent *event) {
int X = event -> x ();
int Y = event -> y ();
if (presse) {
if (A -> bouge (X, Y) || B -> bouge (X, Y) || C -> bouge (X, Y)) {
AB -> droite_pt_pt (A, B);
M -> point_sur_droite_d ();
ABC -> cercle_pt_pt_pt (A, B, C);
N -> point_sur_cercle_c ();
}
M -> bouge (X, Y);
N -> bouge (X, Y);
update ();
Si le déplacement d'un point est en cours (presse = TRUE) alors on modifie ses coordonnées à l'écran (méthode bouge (X, Y);). Si le point en train de bouger est A, B ou C on recalcule la droite (AB) le cercle (ABC) puis la position des points M et N. Si le point en cours de déplacement est M ou N on se contente d'actualiser ses coordonnées. On redessine enfin la figure (méthode update();). NB la méthode bouge (X, Y); n'agit que sur le point en cours de déplacement.
} else {
bool proche = A -> zone (X, Y) || B -> zone (X, Y) || C -> zone (X, Y)
|| M -> zone (X, Y) || N -> zone (X, Y);
if (proche)
setCursor (Qt::PointingHandCursor);
else
setCursor (Qt::ArrowCursor);
}
Si on bouge la souris sans appuyer sur le bouton en change simplement le curseur à proximité de A, B, C, M ou N.
void Fenetre::mouseReleaseEvent (QMouseEvent *) {
A -> stop();
B -> stop();
C -> stop();
M -> stop();
N -> stop();
presse = false;
setCursor (Qt::PointingHandCursor);
}
On relâche de bouton de la souris : on remet alors tous les indicateurs de déplacement à FALSE puis on change le curseur.