introduction à c++ et à wxwidgets - ...renaud/christophe renaud - home page... · généralités...
TRANSCRIPT
1
Introduction à C++et à wxWidgets
Master IGC – 1ère année
Année universitaire 2011/2012
Christophe Renaud
Version 1.5 – 19/09/2011
Introduction
� Objectifs du cours� Introduction au langage objet C++� Introduction à la libraire wxWidgets
� Création d’interfaces graphiques
� Pourquoi C++ ?� Les logiciels professionnels de CAO permettent
l’écriture de greffons (« plugins ») en C++
� Pourquoi wxWidgets ?� Librairie C++ relativement simple
2
Plan du cours
� Programmation orientée objet� Classes et objets� Surcharge d’opérateurs� Héritage� Les flots� La généricité� La STL� wxWidgets
Programmation orientée objetprocédural vs objet (1)
� Programmation procédurale� On décompose le problème en sous-problèmes
plus simples� Chaque sous problème est résolu par la création
d’une procédure ou d’une fonction� Chaque procédure ou fonction agit sur des
données (des variables)� Priorité aux traitements
� Le problème est résolu par “chaînage” des procédures et fonctions
� Langages Cobol, Fortran, Pascal, C, …
3
Programmation orientée objetprocédural vs objet : exemple 1
variable
variable
variable
Fonction
Procédure
Programmation orientée objetprocédural vs objet (2)
� Programmation orientée objet� Priorité aux données
� On réfléchit aux données qui apparaissent dans le problème
� On réfléchit aux fonctionnalités dont peuvent disposer ces données
� On crée un objet qui regroupe ses propres données et ses fonctionnalités
� Le problème est résolu en faisant interagir les différents objets
� Langages C++, Java, C#, …
4
Programmation orientée objetprocédural vs objet : exemple 2
attribut
méthode
attribut
attribut
attribut
méthode
méthode
objet
Attribut = variable interne de l’objet
Méthode = fonction ou procédurequi utilise et/ou agit sur les attributs
Programmation orientée objetprocédural vs objet : exemple 3
vitesse
démarrer
tours/min
accélérer
donnerVitesse
voiture
voiture.démarrer();
voiture.accélérer();
maVitesse=voiture.donnerVitesse();
On demande des informations à l’objet …
On donne des instructionsà l’objet …
5
Programmation orientée objetExercice
� Schématiser une classe Point2D, qui permet de représenter un point en deux dimensions
x y
initialiser
translater
donnerX
Généralités sur le langage C++Historique
� Langage apparu en 1982� Développé par Bjarne Stroustrup (AT&T Labs)� Objectif : ajouter les concepts de la programmation
orientée objet dans le langage C
Chez AT&T Université du Texas
6
Généralités sur le langage C++C et C++
� Surcouche objet ajoutée au langage C� Syntaxe générale du langage C� on peut mélanger de la programmation structurée en C et
de l'objet en C++ !!!
� Fortement déconseillé :� peu lisible, peu compréhensible� difficile à maintenir, à faire évoluer
� Nécessité de :� s’astreindre à une méthodologie purement objet � faire le développement en conséquence
Généralités sur le langage C++éléments de bibliographie
� Programming -- Principles and Practice Using C++ , Bjarne Stroustrup, Addison-Wesley, Décembre 2008.
� Thinking in C++ , Bruce Eckel, version électronique disponible gratuitement
� Programmer en C++ , Claude Delannoy, Eyrolles
7
Premiers pastypes de données
� Types de données� Les mêmes qu’en C :
� int, float, char, …
� Quelques types “spécifiques” dont :� bool : valeurs booléennes truetruetruetrue et falsefalsefalsefalse
bool test = true;…if(test == false) …
� Rappels :� Affectation : opérateur =
� Comparaison : opérateur ==
Premiers pasCompilation
� Dépend� De l’environnement de développement� Du compilateur utilisé
� Sous linux : � Compilateur GNU g++
� Version objet de gcc� Mêmes options générales que gcc
� Par défaut : génère un fichier a.out� Exemples
� g++ essai.cpp a.out� g++ -o essai essai.cpp essai
8
Premiers pasLes commentaires
� Deux types de commentaires� Les commentaires du C
� /* et */ : ce qui se trouve entre ces deux symboles est ignoré par le compilateur
� Les commentaires de fin de ligne� // : tout ce qui suit jusqu’à la fin de ligne est ignoré
par le compilateur
/* Ceci est un commentairequi se trouve surplusieurs lignes. */
// Ceci est un commentaire de fin de ligneint i; // Ceci est un commentaire de fin de ligne
Premiers pasCréation d’un programme
� Point d’entrée :� fonction main() � Syntaxe identique au langage C :
� int main(int argc, char *argv[])
� Exemple (fichier Essai.cpp)
#include <stdio.h>
int main(int argc, char * argv[]){
printf( " hello\n " );
}
9
Premiers pasBlocs & déclaration de variables
� Blocs d’instructions� Délimités par { et }
� Déclaration de variables� N’importe où dans le bloc� Portée limitée au bloc
et aux instructions qui suivent
{int i=0;…while(i<10) i++;…float x = 10.0*i;…
}
Portée de la variable x
Portée de la variable i
Premiers pasDéclaration de variables dans une instruction struc turée
� Exemple
for( int i=0; i<10; i++){tab[i] = i*i;
}
Portée de la variable i
� Avantage� Ne déclarer la variable que là où elle est utile� Permet de réutiliser le nom à d’autres endroits du
bloc où apparaît l’instruction structurée� Application : for, switch, while, do…while
10
Premiers pasLes constantes
const int max = 100;
� Utilisation du qualificatif const
� Portée :� Bloc où la constante est définie (variable locale)� Fichier où la constante est définie (variable globale)
� Avantage :� Contrôle de type / d’utilisation par le compilateur
Premiers pasEntrées sorties de base
� Possibilité d’utiliser les fonctions standards du C� Définies dans <stdio.h>
� Norme ANSI #include <cstdio>
� C++ définit de nouvelles fonctionnalités pour les entrées/sorties� Notions de flots d’entrée/de sortie
� Opérateurs << et >> pour l’envoi ou la réception de données sur un flot
� Plus de précision plus loin dans le cours …
11
int main(int argc, char *argv[]){int n=5;
cout << " valeur :" ;cout << n;cout << endl;
}
Premiers pasEntrées sorties de base – exemple 1
Flot de sortie standard(cf stdout en C)
Opérateur d’envoi de l’opérande droite sur le flot situé en opérande gauche
Passage à laligne suivante(cf ‘\n’ en C)
valeur : 5
int main(int argc, char *argv[]){int n;
cout << " entrez une valeur entière " ;
cin >> n;cout << " valeur : " ;cout << n;cout << endl;
}
Premiers pasEntrées sorties de base – exemple 2
Flot d’entrée standard(cf stdin en C)
Opérateur d’envoi de ce qui est lu sur le flot situé en opérande gauche
vers l’opérande droite
Entrez une valeur entière : 45valeur : 45
12
Premiers pasEntrées sorties de base - chaînage
� L’opérateur << peut être chaîné
� Écrire n, puis écrire un espace, puis écrire x, puis passer à la ligne
int n; float x;int n; float x;
cout << n << " " << x << endl;
� L’opérateur >> peut être chaîné
� Lire n, puis lire x, puis lire s
int n; float x; char s[ 32];int n; float x; char s[32];
cin >> n >> x >> s;
printf( " %d %f\n ",n,x);
scanf( " %d%f%s\n",&n,&x,s);
Premiers pasentrées sorties de base – C ou C++ ?
� <cstdio> (<stdio.h>) reste disponible en C++� On peut utiliser printf , scanf , et tout ce qui y est défini
� Pour les types primaires� printf et scanf : spécificateurs de conversion (%d, %f, …)
� << et >> : se servent du type de la variable
� Pour les objets� printf et scanf inutilisables (pas de spécificateur)
� >> et << : peuvent être redéfinis pour chaque type d’objet
� Homogénéité des E/S
� Éviter de mélanger C et C++ …
13
Premiers pasLes espaces de noms
� Problématique :� Lors de l’utilisation de plusieurs bibliothèques, le
même identificateur (nom de variable, type, classe, fonction, …) peut être défini plusieurs fois
� Définition :� Un espace de noms est un (méta-)identificateur
associé à un ensemble d’identificateurs C++, afin d’éliminer le problème de définitions multiples
� L’espace de nom de la bibliothèque C++ est : std
Premier pasLes espaces de noms – application aux flots standard s
� Utilisation des flots standards� #include <iostream>
� Utilisation de l’espace de noms std� Deux possibilités
#include <iostream>
std::cin >> n >> x;std::cout<< n <<"="<< std::endl;std::cout<< x <<"="<< std::endl;
#include <iostream>using namespace std;
cin >> n >> x;cout << n << "=" << endl;cout << x << "=" << endl;
14
Classes et objetsnotion de classe (1)
� Classe� Modèle d’un objet� Ensemble d’attributs et de méthodes
� Syntaxe C++
class NomDeLaClasse {// attributs// méthodes
};
Attentionle ; est obligatoire
attributs
méthodes
NomDeLaClasse
Classes et objetsnotion de classe (2)
class Voiture {// attributs// méthodes
};
class Voiture {// attributsint vitesse;int toursParMinute;// méthodesvoid demarrer();void accelerer();int donnerVitesse();
};
attributs
méthodes
Voiture
vitesse
donnerVitesse
Voiture
accelerer
demarrer
toursParMinute
15
Classes et objetsnotion de classe (3)
� Coder les méthodes� Peut être fait dans la
classe si le code est court
� Peut être fait à l’extérieur de la classe si le code est long (détaillé plus loin)
class Voiture {// attributsint vitesse;int toursParMinute;// méthodesvoid demarrer(){
toursParMinute = 1000;}void accelerer(){
toursParMinute += 100;vitesse += 5;
}int donnerVitesse(){
return vitesse;}
};
Classes et objetsnotion de classe (4)
� Déclaration d’objets
� Utilisation des objets
Voiture v;
Voiture tv[3];
vitesse
demarrer
toursParMinute
accelerer
donnerVitesse
v.demarrer();v.demarrer();
for(int i=0; i<3; i++){tv[i].demarrer()cout << tv[i].donnerVitesse();
}
vvitesse
demarrer
toursParMinute
accelerer
donnerVitesse
vitesse
demarrer
toursParMinute
accelerer
donnerVitesse
vitesse
demarrer
toursParMinute
accelerer
donnerVitesse
tv
16
Classes et objetsnotion de classe : Exercice
� Donner le code C++ de la classe Point2D
Classes et objetsdéfinition d’une classe & visibilité
� Principe d’encapsulation� Cacher à l’intérieur de la classe tout ce qui n’a
pas à être visible de l’extérieur� 3 niveaux de visibilité
� Privé (private ) : l’attribut / la méthode n’est visible que par les instances de la classe – mode par défaut
� Publique (public ) : l’attribut / la méthode est visible de partout
� Protégé (protected ) : l’attribut / la méthode est visible par héritage
17
Classes et objetsdéfinition d’une classe & visibilité - illustration
class nomDeLaClasse {public :// attributs et méthodes publics
private :// attributs et méthodes privés
protected :// attributs et méthodes protégés
};
� Remarques :� Ordre d’ apparition quelconque des spécificateurs
� Les spécificateurs peuvent apparaître plusieurs fois
class Bidon {public :// attributs publicsprivate : // attributs privéspublic :// méthodes publiquesprivate :// méthodes privées
};
Classes et objetsdéfinition d’une classe & visibilité - exemple
class Voiture {private : // attributs
int vitesse;int toursParMinute;
public : // méthodesvoid demarrer(){
toursParMinute = 1000;}void accelerer(){
toursParMinute += 100;vitesse += 5;
}int donnerVitesse(){
return vitesse;}
};
Voiture v;
v.vitesse = 10; // NON
v.toursParMinute = 1000; // NON
18
Classes et objetsles constructeurs (1)
� Problématique� Création d’un objet
� il faut l’initialiser
� Ses attributs sont généralement privés� Accès impossible
� Constructeurs� Méthodes spéciales
� Appelées lors de la création (instanciation) d’un objet� Leur code permet d’initialiser les attributs de l’objet
créé
Classes et objetsles constructeurs (2)
� Syntaxe : � Constructeur par défaut
� nomDeLaClasse() { code }
� Constructeur paramétrique� nomDeLaClasse(paramètres){ code }
� Remarques :� Doit être public� C++ génère un constructeur par défaut (sans
paramètres) s’il n’existe pas� Comportement ?
19
Classes et objetsles constructeurs (3)
� Exempleclass Voiture {class Voiture {private : // attributs
int vitesse;int toursParMinute;
public : // méthodesVoiture(){
vitesse = 0;toursParMinute = 0;
}Voiture(int v, int t){
vitesse = v;toursParMinute = t;
};
Voiture v;
Voiture vv(0, 1000);
Classes et objetsles constructeurs - Exercice
� Compléter la classe Point2D avec un constructeur par défaut et un constructeur paramétrique
� Étude d’une classe permettant de représenter un point en 3 dimensions
� Étude d’une classe permettant de représenter un cube
20
Plusieurs solutions
P0 P1
P2P3
P4 P5
P6P7
centre
côté
P0
P1
Cube
centreX
dimension
centreY
centreZ
class Cube {private :
float centreX, centreY, centreZ;float dimension;
public:Cube() {
}
Cube(float cx, float cy, float cz, float dim){
}… // suite
}; // fin classe cube
centre
côté
centreX=centreY=centreZ=0.0;dimension = 1.0;
centreX=cx; centreY=cy; centreZ=cz;dimension = dim;
translater(tx,ty,tz)
Cube(cx,cy,cz,dim)
Cube()
afficher()
donnerDimension()
21
class Cube {… // débutvoid translater(float tx, float ty, float tz){
}
float donnerDimension(){
}void afficher(){
}}; // fin classe cube
centre
côté
centreX = centreX + tx;centreY = centreY + ty;centreZ = centreZ + tz;
cout << « cube de centre : (» ;cout << centreX << « , »;cout << centreY << « , »;cout << centreZ << « ) »;cout << « et de côté » << dimension;cout << endl;
translater(tx,ty,tz)
Cube
Cube(cx,cy,cz,dim)
Cube()
centreX
dimension
centreY
centreZ
afficher()
donnerDimension()
return dimension;
Exemple d’utilisation
1
1
x
y
z
1
2
int main(int argc, char *argv[]){
Cube c1;c1.translater(0.0, -2.0, 0.0);c1.afficher();
Cube c2(1.25, 1.75, 1.75, 0.5);c2.translater(0.0, 0.0, 1.0);c2.afficher();
return 0;}
Cube de centre (0.0, -2.0, 0.0) et de côté 1.0
Cube de centre (1.25, 1.75, 2.75) et de côté 0.5
22
P0 P1
P2P3
P4 P5
P6P7
translater(tx,ty,tz)
Cube
Cube(px0, …, pz7)
Cube()
afficher()
donnerDimension()
PY0 PY7
PZ0 PZ7
PX0 PX7 PX[8] PY[8]
PZ[8]
translater(tx,ty,tz)
Cube(sx[8],sy[8],sz[8])
Cube()
afficher()
donnerDimension()
Cube
P0 P1
P2P3
P4 P5
P6P7
PX[8] PY[8]
PZ[8]
translater(tx,ty,tz)
Cube(sx[8],sy[8],sz[8])
Cube()
afficher()
donnerDimension()
Cube
class Cube {private:
float px[8], py[8], pz[8];
public:Cube(){
}
Cube(float sx[8], float sy[8], float sz[8]){
}// suite
};//fin classe Cube
px[0]=px[3]=px[4]=px[7]= -0.5;px[1]=px[2]=px[5]=px[6]= 0.5;py[0]=py[1]=py[4]=py[5]= 0.5;py[3]=py[2]=py[6]=py[7]= -0.5;pz[0]=pz[1]=pz[2]=pz[3]= 0.5;pz[4]=pz[5]=pz[6]=pz[7]= -0.5;
for(int i=0; i<8; i++){px[i] = sx[i]; py[i] = sy[i]; pz[i] = sz[i];
}
23
P0 P1
P2P3
P4 P5
P6P7
PX[8] PY[8]
PZ[8]
translater(tx,ty,tz)
Cube(sx[8],sy[8],sz[8])
Cube()
afficher()
donnerDimension()
Cube
class Cube {private:
float px[8], py[8], pz[8];public:
… // suite
for(int i=0; i<8; i++){px[i] = px[i] + tx;py[i] = py[i] + ty; pz[i] = pz[i] + tz;
}
translater(float tx, float ty, float tz){
}
… // suite2
float donnerDimension() {
}
float dx = px[1]-px[0];return dx;
P0 P1
P2P3
P4 P5
P6P7
PX[8] PY[8]
PZ[8]
translater(tx,ty,tz)
Cube(sx[8],sy[8],sz[8])
Cube()
afficher()
donnerDimension()
Cube
class Cube {private:
float px[8], py[8], pz[8];public:
… // suite2
afficher() {
}
}; // classe Cube
cout << "cube de centre " ;cout << "(" << (px[1]-px[0])/2.0;cout << "," << (py[3]-py[0])/2.0;cout << "," << (pz[0]-pz[4])/2.0;cout << ")" << endl;cout << " et de côté " << px[1]-px[0];cout << endl;
24
Exemple d’utilisation
1
1
x
y
z
1
2
int main(int argc, char *argv[]){
Cube c1;c1.translater(0.0, -2.0, 0.0);c1.afficher();
float px[8]={1.5,2.0,2.0,1.5,1.5,2.0,2.0,1.5};float py[8]={1.5,1.5,1.0,1.0,1.5,1.5,1.0,1.0};float pz[8]={2.0,2.0,2.0,2.0,1.5,1.5,1.5,1.5};
Cube c2(px, py, pz, 0.5);c2.translater(0.0, 0.0, 1.0);c2.afficher();
return 0;}
Cube de centre (0.0, -2.0, 0.0) et de côté 1.0
Cube de centre (1.25, 1.75, 2.75) et de côté 0.5
Classes et objetsle destructeur - principe
� Méthode appelée lorsqu’une instance (un objet) doit être effacée de la mémoire� L’objet n’est plus utile
� Effacement implicite (i.e. variables locales)
� Effacement explicite (i.e. variables dynamiques)� Opérateur delete (cf plus loin dans le cours)
void methodeBidon(){Cube monCube ;…
}
monCube est une variable locale :•Créée à l’entrée dans la méthode•Supprimée à la sortie de la méthode
25
Classes et objetsle destructeur - définition
� Destructeur :� Méthode d’une classe qui est appelée
automatiquement lorsqu’un objet doit être effacé de la mémoire
� Syntaxe : � ~nomDeLaClasse() { code }
� Remarque� Doit être public, en un seul exemplaire� En cas d’absence, génération d’un destructeur
par défaut (comportement ?)
Classes et objetsconstructeurs et destructeur - exemple
class Voiture {class Voiture {private :
int vitesse, toursParMinutes;
public :Voiture(){
vitesse = 0; toursParMinutes = 0;}
Voiture(int v, int t){vitesse = v; toursParMinutes = t;
}
~Voiture(){}
};
Destructeur(ici rien à faire)
Deux constructeurs(publics)
attributs privés
26
Classes et objetssquelette minimal de classe – première version
class NomClasse {class NomClasse {public :
NomClasse(){…
}
~NomClasse(){…
}…
};
Le constructeur par défaut
Le destructeur
En général, rien à y faire, saufen cas de présence d’attributsdynamiques (cf plus loin)
Initialise les attributsavec une valeur pardéfaut.
Classes et objetsConstructeurs et objets attributs - problématique
� Une classe peut posséder des attributs qui soient de « type » classe (un autre objet)
class Point 2D {class Point2D {private :
float x, y;public :
Point2D(){ x=y=0.0;}Point2D(float vx, float vy}{
x=vx; y=vy;}…
};
class Cercle {private :Point2D centre;float rayon;
public :Cercle(float cx, float cy,
float r};…
};
Comment initialiser ces attributs ???Ici : comment affecter (cx,cy) à centre ?
r
cxcy
27
Classes et objetsConstructeurs et objets attributs - initialisation
� Initialiser un objet : � passer par un constructeur� Comment appeler un constructeur précis d’un
objet attribut ?
Cercle(float x, float y, float r) : centre(x,y) {rayon = r;
}
Appel du constructeur Point2D(float,float) pour le membre centre
� Cas de plusieurs objets attributs :� Séparer les appels des constructeurs par une ,
Classes et objetsConstructeurs et objets attributs – exemple
class Point2D {private :
float x, y;public :
Point2D(){x = y = 0.0;
}Point2D(float vx, float vy}{
x = vx; y = vy;cout << "constructeur Point";cout << x << " " << y;cout << endl;
}};
class Cercle {private :
Point2D centre;float rayon;
public :Cercle(){
rayon = 1.0;}Cercle(float x, float y,
float r) : centre(x,y) {rayon = r;cout << "constructeur Cercle";cout << endl;
}
};
28
Classes et objetsConstructeurs et objets attributs – exemple (suite)
#include "Point 2D.hpp"#include "Point2D.hpp"#include "Cercle.hpp"#include <iostream>using namespace std;
int main(int argc, char *argv[]) {
cout << " début main " << endl;
Cercle c(1.0, 2.0, 10.0);
cout << " fin main " << endl;
return 0;}
début mainconstruct Point 2D 1.0 2.0construct Cercle 10.0fin main
Exercice
� Donnez une version de la classe Cube qui utilise des instances de la classe points3D pour représenter ses sommets. � Traitez les deux versions ci-dessous
centre
côté P1
P0
29
centre
côté
class Cube {private:
Point3D centre;float dimension;
public:Cube() : centre() {dimension=1.0;
}
Cube(float cx, float cy, float cz, float dim) : centre(cx, cy, cz)
{dimension = dim;
}
On appelle le constructeur par défaut dela classe Point3D pour l’attribut centre
On appelle le constructeur paramétriquede la classe Point3D pour l’attribut centre
void translater(float tx, float ty, float tz){centre.translater(tx,ty,tz);
}
On appelle la méthodetranslater de la classe Point3D
P1
P0
class Cube {private:
Point3D p0, p1;
public:Cube() : p0(-0.5, -0.5, 0.5), p1(0.5, 0.5, -0.5)
{}
On appelle le constructeur paramétriquede la classe Point3D pour les attributs p0 et p1
void translater(float tx, float ty, float tz){p0.translater(tx,ty,tz);p1.translater(tx,ty,tz);
}
On appelle la méthodetranslater de la classe Point3D
Création d’un cube de côté 1, centré sur l’origine
30
Classes et objetsLes méthodes – les paramètres
� Paramètres formels :� Les paramètres donnés lors de la déclaration de
la méthode
� Paramètres effectifs :� Les variables fournies à la méthode lors de son
appel
translater(float tx, float ty){x += tx; y = ty;
}
int main(int argc, char *argv[]) {float vx, vy;Point2D p;p.translater(1.0, 5.8);p.translater(px , py);
}
Classes et objetsLes méthodes – mécanisme de passage des paramètres
� Passage par valeur� Recopie des paramètres effectifs dans les
paramètres formels
translater(float tx, float ty}{x += tx; y += ty;
}
Point2D p;float vx, vy;
p.translater(vx, vy);
x
translater
y
…
…
p
vx vy
tx ty1. Création des variables locales tx et ty
2. Recopie de la valeur des paramètreseffectifs (vx et vy) dans les paramètresformels (tx et ty)
3. Exécution du code de la méthode4. Suppression des variables locales tx et ty
Impossible de modifier la valeur des paramètres effectifs dans la méthode
31
Classes et objetsLes méthodes – passage de paramètre par référence
� Modifier un paramètre par une méthode� En C : utilisation de pointeurs (difficile)� En C++ : utilisation de références
nomMethode( type &nomParametre)Permet de préciser quele paramètre pourra êtremodifié par la méthode
void remiseAzero(float v){v = 0;
}
void remiseAzero(float &v){v = 0;
}
// X = 5remiseAzero(X);// X = 5
// X = 5remiseAzero(X);// X = 0
Remarque :Rien d’autre à fairepar le programmeur!
Classes et objetsLes méthodes – surcharge des méthodes (1)
� Surcharge des méthodes :� En P.O.O, une classe peut posséder plusieurs
méthodes portant le même nomclass Point2D {private :
float x,y;public :
Point2D();~Point2D();
void move(float dx, float dy);void move(Point2D dp);
};Translation du pointen précisant le vecteur translation
Translation du pointen précisant la valeur de la translation en xet en y
32
Classes et objetsLes méthodes – surcharge des méthodes (2)
� Problème : � Comment les différencier lors d’un appel ?
� En C++ :� Comparaison des paramètres effectifs et formels
� Nombre, type, ordre
� Le type de retour n’est pas pris en compte
Classes et objetsLes méthodes – exemple de surcharge
class Point2D {Private :
float x,y;public :
Point2D();~Point2D();
void move(float dx, float dy);void move(Point2D dp);
};
Méthodes move :Translater le point de ∆x et ∆y
Point2D p, deltaP;float DX, DY;
p.move(DX,DY);
p.move(deltaP);
33
Classes et objetsLes méthodes – surcharge & promotion de type
� En cas de surcharge, le compilateur vérifie le type des paramètres pour déterminer la méthode à appeler :� 1ère étape : correspondance exacte
� Les types des paramètres effectifs et ceux des paramètres formels doivent être identiques
� 2ème étape (si nécessaire) : promotion de type
char, signed char, unsigned char intshort intunsigned short int ou unsigned intfloat double
Classes et objetsLes méthodes – surcharge & promotion de type - exempl es
class Point 2D {class Point2D {Private :
float x,y;public :
Point2D();Point2D(const Point2D &p);~Point2D();
void move(float dx, float dy);void move(Point2D dp);
};
p.move(2.0, 12.0);
p.move(2, 12);
double DX, DY;p.move(DX, DY);
p.move(2, 12.0);
Erreur à la compilation
34
Application
int main(int argc, char *argv[]){float tx, ty, tz;Point2D t;Cercle c;…c.translater(tx, ty);…c.translater(t);
}
class Cercle {private:
Point2D centre;float rayon;
public:…
}; // fin classe cercle
On donne la classe Point2D précédente, l’extrait de classeet le morceau de programme ci-dessous. Donnez le prototype et le code desdeux méthodes translater de la classe Cercle.
void translater(float tx, float ty){
}
void translater(Point2D t){
}
centre.move(tx,ty);
centre.move(t);
Classes et objetsLes méthodes – paramètres par défaut
� Appel d’une méthode :� Un paramètre formel se voit attribuer la valeur du
paramètre effectif correspondant� En C++, possibilité de prévoir une valeur par
défaut pour un paramètre d’une méthode ou d’un constructeur� Si la valeur effective n’est pas fournie au moment de
l’appel, c’est la valeur par défaut qui est utiliséeclass Point 2D{class Point2D{public:
…void move(float dx=0.0,
float dy=0.0);};
p.move();// = p.move(0.0,0.0)
p.move(1.0);// = p.move(1.0,0.0)
p.move(,1.0);//interdit
35
Classes et objetsLes méthodes – règles pour les paramètres par défaut
Lors de la déclaration d’une méthode, tout paramètre avec une valeur pardéfaut doit être suivi par des paramètres ayant tous une valeur par défaut.
Lors de l’appel, si le ième paramètre est omis, alors :• il doit posséder une valeur par défaut ;• tous les paramètres suivants doivent être omis et possèdent une valeur par défaut.
Les valeurs par défaut ne sont spécifiées que dans la déclaration des classes (fichiers .hpp), pas dans leur définition (fichiers .cpp).
void Bidon::fn(int v=0, int w); // interdit
void Bidon::fn(int u, int v=0, int w=0);
fn(5, ,12); // interdit fn(5); // = fn(5,0,0)
Classes et objetsséparation des fichiers - problématique
� Code de chaque méthode décrit dans la classe :� Réduit la lisibilité
� Mélange du modèle et de son implémentation
� Augmente la taille des exécutables� À chaque utilisation d’une
classe, le code est regénéré dans l’exécutable final
� Augmente les temps de compilation� À chaque utilisation d’une
classe, le code est regénéré dans l’exécutable final
class Point2D {private :
float x, y;public :Point2D() {
x = y = 0.0;}Point2D(float vx, float vy}{
x = vx; y = vy;cout << "constructeur Point";cout << x << " " << y;cout << endl;
}move(float tx, float ty){
x += tx; y =+ty;}
};
36
Classes et objetsséparation des fichiers – principe (1)
� Séparer :� La déclaration de la classe (fichier .hpp)� La définition des méthodes de la classe (fichier.cpp)
class Point 2D {class Point2D {private :
float x, y;public :
…void move(float tx,
float ty);…
};
Point2D.hpp
void move(float tx, float ty){x = x + tx;y = y + ty;
}
Point2D.cpp
Problèmes : dans Point2D.cpp
1. On ne connaît pas x et y2. On ne sait pas à quelle classe
appartient la méthode movePas de code …
Classes et objetsséparation des fichiers – principe (2)
1. On inclut la définition de la classe dans le fichier .cpp
2. On précise le nom de la classe à laquelle appartient chacune des méthodes qui s’y trouve
move(float tx, float ty){
#include "Point2D.hpp"
Point2D::Point2D(){x = y = 0.0;
}Point2D::Point2D(float a, float b){
x=a; y=b;}Point2D::~Point2D(){}
void Point2D::move(float tx, float ty){x += tx; y += ty;
}
Point2D.cpp
Inclure la déclarationde la classe pour lacompilation
L’espace de nom de la classeest nécessaire, puisqu’on se trouve à l’extérieur de celle-ci.
37
Application à la classe Cube
class Cube {private :
float centreX, centreY, centreZ;float dimension;
public:Cube();Cube(float cx, float cy, float cz, float dim);void translater(float tx, float ty, float tz);float donnerDimension();
};
Fichier Cube.hpp
#include "Cube.hpp"
Cube:: Cube(){centreX=centreY=centreZ=0.0;dimension=1.0;
}
Cube:: Cube(float cx, float cy, float cz,float dim){
centreX=cx; centreY=cy; centreZ=cz;dimension=dim;
}
void Cube:: translater(float tx, float ty,float tz){
…}float Cube:: donnerDimension(){
…}
Fichier Cube.cpp
Classes et objetsséparation des fichiers – doubles inclusions
� Le problème
class A {…
};
A.hpp
#include "A.hpp"
class B {…
};
B.hpp
#include "A.hpp"#include "B.hpp"class C {
…};
C.hpp
Double déclaration de la classe A ; erreur de compilation
#ifndef _A_HPP#ifndef _A_HPP#define _A_HPP
class A { … };
#endif
Définir et tester la définitiond’une constante propreà la classeIdentifiant au choix
1ère inclusion :La constante et la classesont définies
2nde inclusion :Constante et classe nonredéfinies
38
Classes et objetsLa séparation de fichiers et les paramètres par déf aut : exemple
#ifndef _POINT2D_HPP#define _POINT2D_HPP
class Point2D {private :
float x, y, z;public :
Point2D();Point2D(float a, float b);~Point2D();void move(float dx=0.0,
float dy=0.0);};
#endif // _POINT2D_HPP
Point2D.hpp
#include "Point2D.hpp"
Point2D::Point2D(){x = y = 0.0;
}
Point2D::Point2D(float a, float b){x=a; y=b;
}
Point2D::~Point2D(){}
void Point2D::move(float dx, float dy){x += dx; y+= dy;
}
Point2D.cpp
Classes et objetsLa compilation séparée - problématique
#include "Point3D.hpp"#include "Cube.hpp"
int main(…){Point3D p;Cube c;
…}
essai.cpp
#include "Point3D.hpp"
Point3D::Point3D(){…}
void Point3D::translate(…){…}
Point3D.cpp
…class Point3D {
…};
Point3D.hpp
#include "Cube.hpp"
Cube::Cube(){…}
void Cube::translate(…){…}
Cube.cpp
…class Cube {
…};
Cube.hpp
g++ essai.cpp –o essai
Ne compile ni Point3D.cppni Cube.cpp
39
Classes et objetsLa compilation séparée – principe
� Compilation séparée :� Compiler séparément chaque fichier .cpp
� Réunir les fichiers compilés dans un fichier exécutable
g++ -c essai.cppg++ -c Cube.cppg++ -c Point3D.cpp
essai.oCube.oPoint3D.o
g++ -o essai essai.o Cube.o Point3D.o
+ Facilite le développement de chaque classe séparément- Complexifie la compilation- Augmente le risque d’erreur (oubli de compiler un fichier après sa modification)
Classes et objetsLa compilation séparée – le fichier Makefile
� Utilitaire Make� Permet de gérer les commandes de compilation à
lancer� Se paramètre via un fichier de « commandes »
essai: essai.o Cube.o Point3D.og++ -o essai essai.o Cube.o Point3D.o
essai.o : essai.cppg++ -c essai.cpp
Cube.o: Cube.cpp Cube.hppg++ -c Cube.cpp
Point3D.o: Point3D.cpp Point3D.hppg++ -c Point3D.cpp
Fichier Makefile
make
Lance les commandes decompilation nécessaires, en analysant le contenu du fichier Makefile
40
Classes et objetsAuto-référencement d’une instance - problématique
class A {int a,b,c;
A(int a){a = a;
}
void f(A objet){…
}
void g(…){f( objet_appelant);
}};
Comment différencier l’attribut du paramètre ?
Comment exécuter f sur l’objet appelant ?(qui est bien de classe A)
Classes et objetsAuto-référencement d’une instance - this
� Mot-clé this : référence l’objet appelant� Attention : c’est un pointeur (l’adresse de l’objet)
� Notations : � L’adresse de l’objet : this
� L’objet lui-même : *this
� Un attribut de l’objet : this->attribut ou (*this).attribut
Lever l’ambiguïté entreun paramètre et un
attribut de même nom
Lever l’ambiguïté entreun paramètre et un
attribut de même nom
Passer l’objet lui-mêmeen paramètre à une de
ses méthodes
Passer l’objet lui-mêmeen paramètre à une de
ses méthodes
class A {int a;
A(int a){this->a = a;
}};
class A {class A {…void f(const A& a);void g(…){
…f (*this);…
}};
41
L’héritageproblématique
� En POO� On dispose de classes qui représentent des modèles
d’objets réels� Peuvent être réutilisés sans connaissance a priori de
la manière dont ils ont été implantés (encapsulation)
� Mais …� Les modèles sont parfois trop généraux et/ou
incomplets� On voudrait rajouter des fonctionnalités
� Tout réécrire ???
L’héritagePrincipe
� Héritage =� Mécanisme permettant d’étendre les fonctionnalités
d’une classe existante� On crée une nouvelle classe qui
� Hérite des fonctionnalités d’une classe existante
� Définit de nouvelles fonctionnalités
Voiture
vitesse
donnerVitesse
accelerer
demarrer
toursParMinute
VoitureElectrique
chargeBatterie+
donnerChargeBatterie+
42
L’héritageAvantages
� Avantages :� La classe qui hérite (ici VoitureElectrique) peut
réutiliser tout ce qui a été prévu dans la classe héritée (ici Voiture)
� On ne code que les nouvelles fonctionnalités� Réduction du cycle de développement� Facilite la maintenance
L’héritageTerminologie
� Terminologie� Sur-classe (ou classe mère) :
� La classe qui est héritée � (ici Voiture)
Voiture
vitesse
donnerVitesse
accelerer
demarrer
toursParMinute
VoitureElectrique
chargeBatterie
recharger
donnerChargeBatterie
� Relation d’héritage� « Hérite de »� « Est un(e) »
� Sous-classe (ou classe fille) :� La classe qui hérite
� (ici VoitureElectrique)
43
L’héritageGraphe d’héritage
Voiture
vitesse
donnerVitesse
accelerer
demarrer
toursParMinute
VoitureElectrique
chargeBatterie
recharger
donnerChargeBatterie
VoitureDiesel
quantiteCarburant
donnerQteCarburant
faireLePlein
Voiture v;VoitureElectrique ve;VoitureDiesel vd;
ve.demarrer(); // ouivd.demarrer(); // oui
ve.recharger(); // ouivd.recharger(); // non !!!ve.faireLePlein(); // non !!!vd.faireLePlein(); // oui
ve et vd sont des voitureset peuvent donc utiliser lesméthodes de Voiture
ve et vd ont leurs propresspécificités et ne peuvent pasutiliser celles des autres.
Lien« est un(e) »
Héritagesyntaxe de I’héritage simple
class A {…
};
class B : public A {…
};
« hérite de … »Tous les membres et les méthodespublic de A seront des membres etméthodes public dans B
44
Héritageexemple d’utilisation
class Point3D {private:
float x, y, z;public:
Point3D();Point3D(float x, float y,
float z);~Point3D();…
};
#include "Point3D.hpp "
class Point3DColore : public Point3D {private:
float r,v,b;public:
Point3DColore();Point3DColore(float x, float y,
float z, float r, float v,float b);
~Point3DColore();…
};#include “Point3D.hpp"#include “Point3DColore.hpp"
int main(int argc, char *argv[]){Point3D p1;Point3DColore p2;…
}
Héritagecontrôle des accès par la sous-classe - exemples
� Contrôle d’accès dans une classe :
class Point3D {private:
float x, y, z;public:
Point3D();Point3D(float x, float y,
float z);~Point3D();…
};
class Point3D {public:
float x, y, z;public:
Point3D();Point3D(float x, float y,
float z);~Point3D();…
};
Point3D p;p.x = 5.0; // interdit ( x est privé )
Point3D p;p.x = 5.0; // autorisé ( x est public )
45
Héritagecontrôle des accès par la sous-classe - règles
� Dépend des spécificateurs utilisés dans la sur-classe
public
• Attributs et fonctions accessibles de l’extérieur de la classe• Valable également pour l’héritage
private
• Attributs et fonctions privés à la classe • Inaccessibles par héritage
protected
• Membres et fonctions privés à la classe• Accessibles par héritage pour la classe dérivée• Inaccessibles par les utilisateurs de la classe dérivée
Héritagecontrôle des accès par la sous-classe - exemple
class Point3D {protected:
float x, y, z;public:
Point3D();Point3D(float x, float y,
float z);~Point3D();…
};
#include "Point3D.hpp "
class Point3DColoree : public Point3D {private:
float r,v,b;public:
Point3DColore();Point3DColore(float x, float y, float z,
float rouge,float vert, float bleu);
~Point3DColore();…
};
#include "Point3DColore.hpp"…Point3DColore::Point3DColore(float x, float y, floa t z,
float rouge, float vert, float bleu) {this->x = x; this->y = y; this->z = z;r = rouge; v = vert; b = bleu;
}
Accès autorisé
46
Héritageinitialisation des attributs hérités (1)
� Problématique :� Les membres d’une surclasse sont hérités
� Instanciation de la sous-classe� Appel du constructeur de la sous-classe� Ce constructeur doit initialiser tous les membres
� Définis localement� Hérités
� Problème :� Les membres privés d’une surclasse ne sont pas
accessibles à une sous-classe …
Héritageinitialisation des attributs hérités (2)
� Nécessité d’appeler le constructeur de la surclasse� spécifier le constructeur
à utiliser� Exemple :
#include "Point 3DColore.hpp"#include "Point3DColore.hpp"
Point3DColore::Point3DColore() : Point3D() {r = v = b = 0.0;
}
Point3DColore::Point3DColore(float x, float y, floa t z,float r, float v, float b) : Point3D(x,y,z) {
this->r = r; this->v = v; this->b = b;}
class Point3D {private:
float x, y, z;public:
Point3D();Point3D(float x, float y,
float z);~Point3D();…
};
47
Héritageredéfinition d’attributs et de méthodes – règle d’ap pel
� Redéfinition� Présence d’un élément de même nom (de
membre, de méthode) dans la sur-classe et la classe dérivée
� Lors de l’appel d’un élément dans une instance de :� La sur-classe : c’est l’élément présent dans la
sur-classe qui est utilisé� La classe dérivée : c’est l’élément présent dans la
classe dérivée qui est utilisé� « le local prime … »
Héritageredéfinition d’attributs et de méthodes – exemple
class Point3D {private:
float x, y, z;public:
…void affiche() {
cout << x << y << z;}};
#include "Point3D.hpp "
class Point3DColore : public Point3D {private:
float r,v,b;public:
…void affiche(){
cout << r << v << b;}
};
int main(int argc, char *argv){
Point3D p(0.5, 1.0, 2.5);Point3DColore pc(0.5, 1.0, 2.5, 1.0, 1.0, 0.0);
p.affiche();cout << endl;pc.affiche();
}
0.5 1.0 2.5 1.0 1.0 0.0
48
Héritageredéfinition d’attributs et de méthodes – appel dans la surclasse
� Accès possible aux éléments de la sur-classe� Utiliser l’opérateur de portée (::) précédé par le
nom de la sur-classe� Valable pour les méthodes et pour les membres
class Point3D {private:
float x, y, z;public:
…void affiche(){
cout << x << y << z;}};
#include "Point 3D.hpp "#include "Point3D.hpp "
class Point3DColore : public Point3D {private:
float r,v,b;public:
…void affiche(){
Point3D::affiche();cout << r << v << b;
}};
wxWidgetsintroduction
� wxWidgets
� librairie contenant un grand nombre de classes
permettant la création d'interfaces graphiques
� disponible sur de nombreuses plateformes
� Linux/Unix, Windows, Mac-OS, Windows CE
� disponibles pour de nombreux langages
� Python, Java, Perl, Basic ...
� libre ...
49
wxWidgetsles classes de base : introduction
� Deux classes minimum pour toute application
� wxApp :
� va servir à définir et à lancer l'application
� équivalente à la fonction main d'un programme C++
� n'ouvre aucune fenêtre ...
� wxFrame :
� permet de créer une fenêtre standard
� fenêtre vide par défaut
� classes virtuelles :
� il faut écrire des classes qui en héritent
wxWidgetscréer une application wxWidgets : wxApp
� Développer un classe qui hérite de wxApp
#include "MonApplication.hpp"
bool MonApplication::OnInit(){
return true;
}
MonApplication.cpp
class MonApplication : public wxApp {
public :
bool OnInit(); // init de l’application
};
MonApplication.hpp
#ifndef _MON_APPLI_HPP
#define _MON_APPLI_HPP
#endif
DECLARE_APP(MonApplication)
permet de préciser que la classe MonApplication
est la classe principale du programmepas de ;
Retourne true si tout s’est bien déroulé,false sinon (et fin de l’application)
IMPLEMENT_APP(MonApplication)
Génère le« main »
50
wxWidgetscréer une application wxWidgets : wxFrame (1)
� Développer une classe qui hérite de wxFrame
class Fenetre : public wxFrame {
public :
Fenetre();
};
Fenetre.hpp
#ifndef _FENETRE_HPP
#define _FENETRE_HPP
#endif
#include "Fenetre.hpp"
Fenetre::Fenetre() : wxFrame(??? ) {
…
}
Fenetre.cpp
Quels paramètres ???
Appel du constructeur de lasur-classe
wxWidgetscréer une application wxWidgets : wxFrame (2)
wxFrame(wxFrame *parent,int numeroFenêtre,char* titreFenêtre,wxPoint coordonneesCoin,wxSize tailleFenêtre)
Adresse de la fenêtre « parent »(cas des fenêtres contenant dessous-fenêtres) ;
Numéro à attribuer à la fenêtre(en cas d’utilisation de plusieursfenêtres, pour les différencier)
Texte devant apparaître dansla barre de titre de la fenêtre
Coordonnées du coin supérieurgauche de la fenêtre - en pixels
Taille de la fenêtre(largeur, hauteur) – en pixels
51
wxWidgetscréer une application wxWidgets : wxFrame (3)
#include "Fenetre.hpp"
Fenetre::Fenetre() :
wxFrame( NULL,
-1,
“Mon application”,
wxPoint(100, 100),
wxSize(300, 200)
)
{
}
Fenetre.cpp
Pas de fenêtre « parent »
Pas de numéro de fenêtreà gérer
Coin supérieur gauche de lafenêtre en (100,100)
Fenêtre de 300 pixels de largeet 200 pixels de hautwxPoint et wxSize sont des
classes fournies par wxWidgets
wxWidgetscréer une application wxWidgets : wxFrame (4)
� Rajouter les bibliothèques wxWidgets
#ifndef _FENETRE_HPP
#define _FENETRE_HPP
class Fenetre : public wxFrame {
public :
Fenetre();
};
#endif
Fenetre.hpp#include "Fenetre.hpp"
Fenetre::Fenetre() :
wxFrame( NULL,
-1,
“Mon application”,
wxPoint(100, 100),
wxSize(300, 200)
)
{
}
MaFenetre.cpp
#include <wx/wx.h>
52
wxWidgetsAjouter une fenêtre à l’application (1)
� à ce stade :� Une classe application qui ne fait … rien !� Une classe permettant de représenter une fenêtre
Ajouter la fenêtre à l’application
MonApplication Fenetre
Relier la fenêtreà l’application
wxWidgetsAjouter une fenêtre à l’application (2)
#ifndef _MON_APPLI_HPP
#define _MON_APPLI_HPP
class MonApplication : public wxApp {
public :
bool OnInit(); // init de l’application
};
DECLARE_APP(MonApplication)
#endif
MonApplication.hpp
private:Fenetre *maFenetre;
#include “Fenetre.hpp”
#include <wx/wx.h>
Cette variable doit être un pointeur …
Déclarer une variable interneà l’application qui permettra dereprésenter la fenêtre qui y sera incluse
Inclure la définition de la classepermettant de représenter desfenêtres
Inclure les bibliothèques wxWidgets
53
wxWidgetsAjouter une fenêtre à l’application (3)
#include "MonApplication.hpp"
IMPLEMENT_APP(MonApplication)
bool MonApplication::OnInit(){
maFenetre = new Fenetre();
maFenetre->Show(TRUE);
SetTopWindow(maFenetre);
return true;
}
MonApplication.cpp
Création de la fenêtre
Rendre visible la fenêtre
Préciser que la fenêtre estla fenêtre principale
wxWidgetsQuelques composants - wxPanel
� Fenêtre sur laquelle on place d’autres composants et leurs contrôles
� En général, placé dans la fenêtre principale
#include<wx/wx.h>
class Fenetre : public wxFrame {
private:
wxPanel *panneau;public :
Fenetre();
};
Fenetre.hpp
#include "Fenetre.hpp"
Fenetre::Fenetre() :
wxFrame( NULL, -1, “Mon application”,
wxPoint(100, 100), wxSize(300, 200)
)
{
panneau = new wxPanel(this);}
MaFenetre.cpp
Rattacher le panneau à la fenêtre appelante
54
wxWidgetsQuelques composants - wxStaticText
� Permet d’afficher un texte non modifiable dans un panneau
wxStaticText(wxWindow *parent,wxWindowID id,wxString &texte,wxPoint &position,wxSize &taille,long style,…)
La fenêtre parente à laquelle estrattaché le texte. Ne doit pas être NULL
Un entier identifiant le texte
Le texte à afficher
Position du coin supérieur gauchedu texte – en pixels
Taille du texte (largeur x hauteur)en pixels
Alignement du texte sur sa zone :wxALIGN_LEFT, wxALIGN_RIGHT,wxALIGN_CENTRE
wxWidgetswxStaticText - exemple
#ifndef _FENETRE_HPP
#define _FENETRE_HPP
#include<wx/wx.h>
#include <wx/panel.h>
class Fenetre : public wxFrame {
private:
wxPanel *panneau;
wxStaticText *monTexte;public :
Fenetre();
};
#endif
Fenetre.hpp#include "Fenetre.hpp“
Fenetre::Fenetre() :
wxFrame( NULL, -1, “Mon application”,
wxPoint(100, 100), wxSize(300, 200)
) {
panneau = new wxPanel(this);
monTexte = new wxStaticText(panneau, -1,
“le texte à afficher”,
wxPoint(10,10),wxSize(200,10));
}// Fenetre()
MaFenetre.cpp
55
wxWidgetsQuelques composants – wxTextCtrl
� Permet d’ajouter une zone de texte pour la saisie et/ou l’affichage
wxTextCtrl(wxWindow *parent,wxWindowID id,wxString &valeur,wxPoint &position,wxSize &taille,long style,…)
La fenêtre parente à laquelle estrattaché la zone. Ne doit pas être NULL
Un entier identifiant la zone
Le texte initial à afficher dans la zone
Position du coin supérieur gauchede la zone – en pixels
Taille de la zone (largeur x hauteur)en pixels
Alignement du texte sur sa zone :wxTE_LEFT, wxTE_RIGHT,wxTE_CENTRE
Autres propriétés paramétrables …
wxWidgetswxTextCtrl - exemple
#ifndef _FENETRE_HPP
#define _FENETRE_HPP
#include<wx/wx.h>
#include <wx/wxPanel.h>
class Fenetre : public wxFrame {
private:
wxPanel *panneau;
wxTextCtrl *maZone;public :
Fenetre();
};
#endif
Fenetre.hpp#include "Fenetre.hpp“
Fenetre::Fenetre() :
wxFrame( NULL, -1, “Mon application”,
wxPoint(100, 100), wxSize(300, 200)
) {
panneau = new wxPanel(this);
maZone = new wxTextCtrl(panneau, -1,
“”,
wxPoint(10,10),wxSize(200,10));
}// Fenetre()
MaFenetre.cpp
Zone initialement vide
56
wxWidgetsQuelques composants – wxButton
� Permet d’afficher et de gérer un bouton dans un panneau
wxButton(wxWindow *parent,wxWindowID id,wxString &label,wxPoint &position,wxSize &taille,long style,…)
La fenêtre parente à laquelle estrattaché le bouton. Ne doit pas être NULL
Un entier identifiant le bouton
Le texte devant figurer sur le bouton
Position du coin supérieur gauchedu bouton – en pixels
Taille du bouton (largeur x hauteur)en pixels
Alignement du texte sur le bouton :wxBU_LEFT, wxBU_RIGHT,wxBU_BOTTOM, wxBU_TOP
wxWidgetswxButton - exemple
#ifndef _FENETRE_HPP
#define _FENETRE_HPP
#include<wx/wx.h>
#include <wx/panel.h>
class Fenetre : public wxFrame {
private:
wxPanel *panneau;
wxButton *monBouton;public :
Fenetre();
};
#endif
Fenetre.hpp #include "Fenetre.hpp“
const int ID_BOUTON = 1;
Fenetre::Fenetre() :
wxFrame( NULL, -1, “Mon application”,
wxPoint(100, 100), wxSize(300, 200)
) {
panneau = new wxPanel(this);
monBouton = new wxButton(panneau,ID_BOUTON,
“ESSAI”,wxPoint(10,10),wxSize(20,10));
}// Fenetre()
MaFenetre.cpp
57
wxWidgetsGestion des événements – problématique
� Événements = modification de l’état d’un périphérique d’entrée� Déplacement ou clic souris, Appui sur une touche
du clavier, …
� Gérés par le système d’exploitation� Chaque événement est transmis à l’application
concernée (fenêtre active)� Chaque application possède un gestionnaire
d’événements� Attend l’arrivée d’un événement� Gère cet événement si nécessaire
Boucle événementielle
wxWidgetsGestion des événements – principe
� Généralement� Gestion relativement complexe
� wxWidgets simplifie cette gestion� Chaque composant gère ses propres événements� Au niveau de l’application, utilisation d’un petit
nombre de macros prédéfinies
� Du point de vue du développeur� Préciser que l’application gère des événements� Donner la liste des événements gérés� Associer un méthode à chaque événement
58
wxWidgetsGestion des événements – activation
� Une macro à utiliser pour activer la gestion des événements
#ifndef _FENETRE_HPP
#define _FENETRE_HPP
#include<wx/wx.h>
class Fenetre : public wxFrame {
private:
wxPanel *panneau;
wxButton *monBouton;
public :
Fenetre();
DECLARE_EVENT_TABLE()};
#endif
Fenetre.hpp
Effectue les opérations internesqui permettront à la fenêtre de capturer les événements(création d’une table qui contiendrales événements qui seront géréspar l’application)
wxWidgetsGestion des événements – capture (1)
� Prévoir une méthode pour chaque événement à traiter
…
class Fenetre : public wxFrame {
private:
wxPanel *panneau;
wxButton *monBouton;
public :
Fenetre();
void gererBouton(wxCommandEvent &event);
DECLARE_EVENT_TABLE()};
…
Fenetre.hpp
Le paramètre est un événement :Permet d’analyser l’événement dansla méthode.
59
wxWidgetsGestion des événements – capture (2)
#include "Fenetre.hpp“
const int ID_BOUTON = 1;
Fenetre::Fenetre() : wxFrame(…) {
panneau = new wxPanel(this);
monBouton =
new wxButton(panneau, ID_BOUTON, …);
}// Fenetre()
void Fenetre::gererBouton(wxCommandEvent &event){
wxMessageBox(“bouton appuyé”);
}
MaFenetre.cpp
� Ecrire le code des méthodes qui gèrent chaque événement
Ouvre une fenêtre indépendantequi affiche le message et unbouton OK
wxWidgetsGestion des événements – capture (3)
� Connecter chaque événement à la méthode qui doit le traiter
#include "Fenetre.hpp“
const int ID_BOUTON = 1;
Fenetre::Fenetre() : wxFrame(…) {
panneau = new wxPanel(this);
monBouton =
new wxButton(panneau, ID_BOUTON, …);
}// Fenetre()
void Fenetre::gererBouton(wxCommandEvent &event){
wxMessageBox(“bouton appuyé”);
}
BEGIN_EVENT_TABLE(Fenetre, wxFrame)
EVT_BUTTON(ID_BOUTON, Fenetre::gererBouton)
END_EVENT_TABLE()
MaFenetre.cpp
Début et fin de définition de latable d’événements
Une macro différente par type d’événement à gérer
On fait le lien entre l’objet qui génèrel’événement et la méthode qui gèrecet événement
60
wxWidgetsGestion des événements – quelques macros
BEGIN_EVENT_TABLE(…)EVT_BUTTON( id , méthode)EVT_MENU( id, méthode)EVT_KEY_DOWN(méthode)EVT_MOUSE_EVENTS(méthode)
END_EVENT_TABLE
Associe « méthode » aux événements qui se produisent sur le bouton numéroté id
Associe « méthode » aux événementsqui se produisent sur le menu numéro id
Associe « méthode » à tous lesévénements qui se produisent sur le clavier
Associe « méthode » à tous les événements issus de la souris