Il s'agit dans cet exemple de tracer la courbe de la fonction f (x) = m x2. C'est un curseur qui permet la récupération de la valeur du paramètre m.
Répertoire : fparm. Trois fichiers : 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/curseur.h" #include "geo2D/courbe.h" class mx2: public fonction { public: double m; mx2 (double m); double image (double x); };
La fonction dépendant d'un paramètre est une sur-classe de la classe fonction.
class Fenetre: public QWidget { Q_OBJECT public: repere *R; curseur *mcurs; mx2 *f; courbe *c;
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).
* * test */ #include "fenetre.h" bool fonction::def (double) { return true; } double fonction::image (double) { return 0.0; }
La classe fonction étant virtuelle il faut la définir même si cette définition est bidon.
mx2::mx2 (double m) { mx2::m = m; } double mx2::image (double x) { return m * x * x; }
On construit ici l'ensemble de définition de la fonction carré mx2 et l'expression de l'image de x.
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.
R = new repere (300, 225, 600, 450, 50.0, 50.0, 1.0, 1.0); mcurs = new curseur (-4.0, 4.0, 1.0, 400, 100, 100, "m", R); f = new mx2 (1); c = new courbe (f, NULL, R);
On crée ici les objets géométriques : le repère, le curseur (de -4 à 4, valeur initiale 1, pas = 100 / 8 = 0,08), la fonction et la courbe de la fonction.
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); mcurs -> trace (&painter); c -> trace (&painter); }
On redessine ici la figure : on peint le fond en blanc, on trace le repère en rouge puis le curseur et la courbe.
void Fenetre::mousePressEvent (QMouseEvent *event) { int X = event -> x (); int Y = event -> y (); presse = mcurs -> select (X, Y) || mcurs -> select_curseur (X, Y); if (presse) setCursor (Qt::ClosedHandCursor); }
On teste, dans cet ordre, si la souris est proche du bouton du curseur puis du curseur lui-même.
void Fenetre::mouseMoveEvent (QMouseEvent *event) { int X = event -> x (); int Y = event -> y (); if (presse) { mcurs -> bouge (X, Y); mcurs -> bouge_curseur (X, Y); f -> m = mcurs -> valeur (); update ();
On met à jour le paramètre puis on relance le tracé..
} else { if (mcurs -> zone (X, Y) || mcurs -> zone_curseur (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é du curseur ou de son bouton.
void Fenetre::mouseReleaseEvent (QMouseEvent *) { mcurs -> stop ();
mcurs -> stop_curseur (); 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.