Il s'agit dans cet exemple de tracer la courbe de la fonction inverse, un point M sur l'axe des x puis N le point de même abscisse sur la courbe de la fonction. De plus O l'origine du repère peut être déplacé à l'aide la souris, son déplacement entraine bien sûr le déplacement du repère, de la courbe et des points M et N.

Répertoire : fonct. 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 "geo2D/courbe.h" #include "geo2D/point_sur_droite.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;
droite *ox;
fonction *f;
courbe *c;
point_sur_droite *M;
pt *N;
point_libre *O;
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).
/*
* fonct
*/
#include "fenetre.h"
#define W 600
#define H 450
#define W0 W / 2
#define H0 H / 2
bool fonction::def (double x) {
return x != 0;
}
double fonction::image (double x) {
return 1 / x;
}
On définit ici l'ensemble de définition de la fonction inverse ainsi que l'image de x.
Fenetre::Fenetre (QWidget *parent): QWidget (parent) {
setGeometry (0, 0, W, H);
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 (W0, H0, W, H, 50.0, 50.0, 1.0, 1.0);
ox = new droite (0, 1, 0, NULL, R);
M = new point_sur_droite (-1.0, 0.0, ox, "M", R);
f = new fonction;
c = new courbe (f, "y = 1 / x", R);
N = new pt (-1.0, -1.0, "N", R);
O = new point_libre (0.0, 0.0, "O", R);
On crée ici les objets géométriques : le repère, l'axe des abscisses, la fonction, la courbe de la fonction et les points M, N et O.
void Fenetre::paintEvent (QPaintEvent *) {
setPalette (QPalette (QColor (255, 255, 255)));
setAutoFillBackground (true);
QPainter painter (this);
painter.setPen (Qt::red);
R -> trace (&painter);
M -> trace (&painter);
O -> trace (&painter);
painter.setPen (Qt::blue);
c -> 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 O et M et enfin la courbe et le point N.
void Fenetre::mousePressEvent (QMouseEvent *event) {
int X = event -> x ();
int Y = event -> y ();
presse = M -> select (X, Y) || O -> select (X, Y);
if (presse)
setCursor (Qt::ClosedHandCursor);
}
On teste, dans cet ordre, si la souris est proche de M ou de O. 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 (O -> bouge (X, Y)) {
R -> X0 = (X > W) ? W : (X < 0) ? 0 : X;
R -> Y0 = (Y > H) ? H : (Y < 0) ? 0 : Y;
O -> pt_x_y (0.0, 0.0);
M -> pt_x_y ((*M).x, (*M).y);
}
M -> bouge (X, Y);
double x = M -> x;
N -> pt_x_y (x, f -> image (x));
update ();
Si O est en cours de déplacement on modifie le repère en faisant en sorte que le point O ne sorte pas de l'écran puis on remet à jour O et M. Si M bouge, on remet à jour les coordonnées du point N.
} else {
if (M -> zone (X, Y) || O -> zone (X, Y))
setCursor (Qt::PointingHandCursor);
else
setCursor (Qt::ArrowCursor);
}
}
Si on bouge la souris sans appuyer sur le bouton en change simplement le curseur à proximité de M ou O.
void Fenetre::mouseReleaseEvent (QMouseEvent *) {
M -> stop ();
O -> 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.