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.