Trois fichiers sont nécessaires dans ce modèle
#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.
#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
#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.