Interfaces graphiques en C++ avec wxWidget/Évenements

IHM en C++ avec wxWidget
Interfaces graphiques en C++ avec wxWidget
Interfaces graphiques en C++ avec wxWidget
Sommaire
Liens
Modifier ce modèle

Intercepter des événements

modifier

Notions abordées :

modifier
  • nouveaux composants graphiques
  • la classe wxPanel
  • la classe wxButton
  • la classe wxStaticText
  • la classe wxTextCtrl
  • la classe wxColour
  • le modèle événementiel
  • la classe wxEventCommand
  • la classe wxString
  • la fonction wxMessageBox


Screenshot

modifier

Fichier:WxWidgetSomme.jpg

Présentation de l'application

modifier

L'objectif de cette leçon est d'avoir deux champs texte éditables dans lesquels l'utilisateur peut saisir des réels ainsi qu'un bouton « calculer ». Si on clique sur le bouton, on voit apparaître la somme des 2 réels dans un troisième champ texte non éditable.

Présentation de quelques composants graphiques

modifier

Nous avons vu lors de la première leçon qu'une fenêtre hérite de la classe wxFrame. Nous allons rajouter différents composants graphiques dans notre fenêtre : du texte, des champs texte éditables et des boutons. Pour cela, il faut commencer par positionner un wxPanel à l'intérieur de notre fenêtre. Si panel est un pointeur vers notre wxPanel, on peut tout simplement écrire dans le constructeur de notre fenêtre :

panel = new wxPanel(this);


Maintenant, nous allons mettre différents composants graphiques sur notre panel :

  • du texte : il suffit de rajouter des wxStaticText. Le constructeur de ces wxStaticText ont besoin des informations suivantes :
    • le « père » de notre composant graphique : il s'agira de notre panel.
    • un entier identifiant notre composant : nous n'avons pas besoin d'utiliser un tel identifiant pour nos champs texte, nous mettrons alors la valeur -1.
    • la position de notre champ texte en utilisant la classe wxPoint.
    • la taille de notre champ texte en utilisant le classe wxSize.
    • Pour rajouter un champ texte sur notre wxPanel, nous écrirons par exemple :
textX= new wxStaticText(panel,-1,"Valeur de X : ",wxPoint(10,20),wxSize(100,20));


Il s'affichera alors le texte "Valeur de X :" aux coordonnées 10,20 dans un rectangle de 100x20 pixels.

  • des champs texte éditables :
    • le composant graphique correspondant s'appelle wxTextCtrl. Le constructeur de ce composant a besoin des mêmes paramètres que le constructeur de wxStaticText. Il est possible de rendre le champ texte inéditable en utilisant la méthode SetEditable(false). Il est possible de modifier la couleur de notre champ texte en utilisant la méthode SetBackgroundColour(wxColour(200,200,200)); La classe wxColour permet de représenter une couleur sous la forme rouge-vert-bleu où chaque composante est un entier entre 0 et 255.
    • Pour rajouter un champ texte éditable sur notre wxPanel, nous écrirons par exemple :
editX=new wxTextCtrl(panel,-1,"",wxPoint(120,20),wxSize(100,20));


  • des boutons :
    • nous utiliserons alors la classe wxButton. Le constructeur de ce composant aura besoin des informations suivantes :
    • le « père » de notre composant graphique : il s'agira de notre panel.
    • un entier identifiant notre composant : lorsque nous cliquerons sur notre bouton, nous aurons besoin d'un identifiant pour ce bouton. Nous utiliserons une constante entière générée par exemple par un type énuméré.
    • la position de notre champ texte en utilisant la classe wxPoint.
    • la taille de notre champ texte en utilisant le classe wxSize.
    • Pour rajouter un bouton sur notre wxPanel, nous écrirons par exemple :
buCompute=new wxButton(panel,BUTTONCOMPUTE_ID,"CALCULER",wxPoint(240,50));


Structuration en classes

modifier

Notre application somme comportera 2 classes : la classe SommeAppli qui représente notre application et qui hérite de wxApp et la classe SommeWin qui héritera de wxframe et qui sera notre principale fenêtre. Pour chacune de ces classes nous allons créer un fichier .h et un fichier .cpp. Nous aurons donc 4 fichiers au total :

  • SommeAppli.h
  • SommeAppli.cpp
  • SommeWin.h
  • SommeWin.cpp

La classe SommeAppli

modifier

Rien de nouveau par rapport à la leçon numéro 1. Le fichier SommeAppli.h est donc le suivant :

#ifndef SOMMEAPPLI_H
#define SOMMEAPPLI_H

#include<wx/wx.h>
#include"SommeWin.h"

class SommeAppli : public wxApp
{
public:
    bool OnInit();

protected:
    SommeWin * window;
};

DECLARE_APP(SommeAppli)

#endif


Le fichier SommeAppli.cpp est :

#include"SommeAppli.h"

IMPLEMENT_APP(SommeAppli)

bool SommeAppli::OnInit()
{
  window=new SommeWin();
  window->Show(TRUE);
  SetTopWindow(window);
  return true;
}


Le modèle événementiel

modifier

Lorsque l'utilisateur va cliquer sur le bouton, il faudra effectuer une opération particulière : afficher dans un champ texte la somme de 2 réels. Il faut donc dire à l'application que lorsqu'on cliquera sur le bouton ayant un identifiant donné, on actionnera une méthode donnée. Pour cela, nous écrirons dans la classe SommeWin.h la macro :

DECLARE_EVENT_TABLE()

Cela signifie que notre classe va devoir gérer des événements.
Notre bouton portera l'identifiant BUTTONCOMPUTE_ID. Lorsqu'on cliquera sur ce bouton, on appellera la méthode compute. Pour effectuer cette association, on écrira dans le fichier SommeWin.cpp :

BEGIN_EVENT_TABLE(SommeWin,wxFrame)
EVT_BUTTON(BUTTONCOMPUTE_ID,SommeWin::compute)
END_EVENT_TABLE()

La méthode compute sera définie dans la classe SommeWin de la manière suivante :

void compute(wxCommandEvent &event);


Le paramètre event permet d'avoir différentes informations sur l'événement qui vient de se produire : nous n'utiliserons pas ici ces informations.

La méthode compute

modifier

Dans la méthode compute, il faudra récupérer les chaînes de caractères situées dans les 2 champs texte éditables. Pour cela, il suffit d'appeler la méthode GetValue() de la classe wxTextCtrl pour récupérer la chaîne de caractères qui sera une instance de la classe wxString. Il faudra ensuite transformer cette chaîne en double. Pour cela on utilisera la méthode bool ToDouble(double & x); de la classe wxString. Cette méthode renvoie le booléen true si la chaîne est effectivement un réel. Dans ce cas, la valeur de la chaîne transformée en double est mise dans x. Si l'utilisateur a tapé une chaîne qui n'est pas un réel, alors la méthode ToDouble renverra false.
Lorsqu'on aura récupéré les 2 réels tapés, nous pourrons aisément calculer la somme des 2 double : il faudra alors transformer ce double en une wxString. Pour cela, nous pourrons utiliser la méthode sprintf(...) de wxString qui permet d'écrire ce que l'on veut dans une chaîne de caractères avec la même syntaxe que la commande printf du C. Si jamais l'utilisateur tape des valeurs erronées, nous ouvrirons une boîte de dialogue qui comportera un message d'erreur et un bouton OK et qui bloquera l'application tant que l'utilisateur n'appuiera pas sur le bouton OK : une telle boite de dialogue est dite modale. Il suffit d'appeler la fonction wxMessageBox(...). Par exemple si on appelle wxMessageBox("Données erronées","ERREUR"); , il s'ouvre une boîte de dialogue modale dans laquelle il est écrit « Données erronées » et dans la barre du haut de cette boîte il est écrit « ERREUR ».

La classe SommeWin

modifier

Le fichier SommeWin.h est le suivant :

#ifndef SOMMEWIN_H
#define SOMMEWIN_H

#include<wx/wx.h>

enum
{
  BUTTONCOMPUTE_ID
};

class SommeWin : public wxFrame
{
public:
    SommeWin();

protected:
    wxPanel * panel;
    wxButton *buCompute;
    wxStaticText *textX,*textY,*textS;
    wxTextCtrl *editX,*editY,*editS;

    void compute(wxCommandEvent &event);

    DECLARE_EVENT_TABLE()
};

#endif


Le fichier SommeWin.cpp est le suivant :

#include"SommeWin.h"
#include<wx/colour.h>

SommeWin::SommeWin()
    : wxFrame(NULL,-1,"Distance")
{
  panel= new wxPanel(this);

  textX= new wxStaticText(panel,-1,"Valeur de X : ",wxPoint(10,20),wxSize(100,20));
  textY= new wxStaticText(panel,-1,"Valeur de Y : ",wxPoint(10,50),wxSize(100,20));
  textS= new wxStaticText(panel,-1,"X+Y vaut : ",wxPoint(10,80),wxSize(100,20));

  editX=new wxTextCtrl(panel,-1,"",wxPoint(120,20),wxSize(100,20));
  editY=new wxTextCtrl(panel,-1,"",wxPoint(120,50),wxSize(100,20));
  editS=new wxTextCtrl(panel,-1,"",wxPoint(120,80),wxSize(100,20));
  editS->SetEditable(false);
  editS->SetBackgroundColour(wxColour(200,200,200));
  buCompute=new wxButton(panel,BUTTONCOMPUTE_ID,"CALCULER",wxPoint(240,50));
}

void SommeWin::compute(wxCommandEvent &event)
{
  double x,y,s;
  bool okX,okY;
  wxString sS, sX, sY;

  sX=editX->GetValue();
  okX=sX.ToDouble(&x);
  sY=editY->GetValue();
  okY=sY.ToDouble(&y);

if(okX && okY)
  {
    s=x+y;
    sS.sprintf("%lf",s);
    editS->SetValue(sS);
  }
else
  {
    editS->SetValue("");
    wxMessageBox("Données erronnées","ERREUR");
  }
}

BEGIN_EVENT_TABLE(SommeWin,wxFrame)
    EVT_BUTTON(BUTTONCOMPUTE_ID,SommeWin::compute)
END_EVENT_TABLE()