Apprendre à programmer en C++ avec la bibliothèque wxWidgets : sixième partie

CGi

Les boîtes de dialogues personnalisées.

Dans cette sixième partie de cette série de tutoriels, vous allez apprendre à créer des boîtes de dialogue personnalisées avec la bibliothèque wxWidgets.

Un espace de dialogue vous est proposé sur le forum. N'hésitez pas à apporter vos commentaires sur le lien ci-dessous, si vous avez des remarques concernant ce tutoriel. ♪

Commentez

- Titre : Apprendre à programmer en C++ avec la bibliothèque wxWidgets : sixième partie

- Auteur : CGi

- Parution : 25 juin 2004

- Mise à jour : 14 octobre 2016

- Licence : Copyright ® 2016 CGi. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.

Sommaire

- I. Introduction

- II. La boîte de dialogue

- III. Appel de la boîte de dialogue

- IV. Code source complet

- IV-A. wxwin1.h

- IV-B. wxwin1.cpp

- V. Remarques sur ce document

I - Introduction

Dans ce chapitre nous allons voir l'élaboration d'une boîte de dialogue personnalisée, qui sera constituée de trois boutons radio donnant le choix entre les trois premiers chiffres de notre chère numération décimale, un bouton 'OK' et un bouton 'Annuler'.

Suite à sa validation par le bouton 'OK' nous enregistrons sa valeur (N° du bouton radio coché) et nous l'afficherons sur la fenêtre principale. À son appel suivant, la valeur doit lui être restituée afin qu'elle la reflète sur l'état des boutons radio .

II - La boîte de dialogue

La boîte de dialogue sera sous forme d'un objet dont nous allons d'abord définir le type, c'est-à-dire une classe nommée : Dialog descendant de wxDialog, dont nous pouvons voir le prototype dans l'extrait de code ci-dessous.

class Dialog : public wxDialog
{
public:
Dialog(wxWindow* parent, wxWindowID id, const wxString& title, int nb = 0);
int GetValue();
void SetValue(int);
private:
wxRadioButton *RadioBouton1;
wxRadioButton *RadioBouton2;
wxRadioButton *RadioBouton3;
};

La déclaration de son constructeur ressemble à celle d'un contrôle. Le premier paramètre est un pointeur sur la fenêtre parent qui dans ce cas peut être 'null', le 2e est un identificateur de fenêtre, le 3e est le titre de la fenêtre et le paramètre 'nb' de type int a été ajouté dans la classe dérivée, il servira à cocher le bouton radio correspondant lors de sa construction. Il est affecté d'une valeur par défaut à zéro s'il n'est pas renseigné.
Nous déclarons deux méthodes public GetValue et SetValue servant à retourner ou affecter l'état des boutons radio , dont on peut voir l'implémentation dans l'extrait de code ci-dessous.

int Dialog::GetValue()
{
int x = 0;
if( RadioBouton1->GetValue() ) x = 1;
if( RadioBouton2->GetValue() ) x = 2;
if( RadioBouton3->GetValue() ) x = 3;
return x;
}
//------------------------------------------------------------------------------
void Dialog::SetValue(int x)
{
switch(x)
{
case 1 : RadioBouton1->SetValue(true);
break;
case 2 : RadioBouton2->SetValue(true);
break;
case 3 : RadioBouton3->SetValue(true);
break;
}
}

GetValue retourne un entier indiquant lequel des boutons radio est coché et SetValue reçoit un entier comme paramètre permettant de cocher le radio bouton de notre choix.
Les contrôles de la boîte de dialogue lui sont ajoutés dans la définition de son constructeur de la même façon que pour une fenêtre (voir le code source du constructeur à la fin de cet article). Ils seront intégrés dans des sizers (voir chapitre sur les sizers). Une remarque sur la construction des boutons, ils sont affectés d'identificateurs définis dans la bibliothèque : wxID_OK et wxID_CANCEL. Ces identificateurs les lient à des événements provoquant la fermeture de la boîte de dialogue et affectant une valeur de retour à la méthode d'appel ShowModal de la boîte de dialogue.

wxButton *MonBouton1 = new wxButton(this,wxID_OK,"Ok");
wxButton *MonBouton2 = new wxButton(this,wxID_CANCEL,"Annuler");

Dans son constructeur nous appellerons sa méthode SetValue afin d'initialiser les valeurs de ses boutons radio avec le paramètre 'nb' dès sa construction.

III - Appel de la boîte de dialogue

Nous l'appelons depuis le menu de la fenêtre principale : 'Fichier' -> 'Dialogue' qui lui déclenche une méthode gestionnaire d'événement nommée dans l'exemple : OnDialog où sera construite notre boîte de dialogue. Chiffre est une donnée membre de la fenêtre principale mémorisant la valeur servant pour exemple. La boîte de dialogue est rendue visible par sa méthode ShowModal dont on traitera la valeur de retour. Dans l'exemple si elle est fermée par le bouton 'OK' nous récupérons le N° du bouton radio coché à l'aide de la méthode GetValue afin de le mémoriser dans la donnée membre 'Chiffre' et nous l'affichons en toutes lettres sur la fiche principale dans un wxStaticText nommé Label.

void Frame::OnDialog(wxCommandEvent& WXUNUSED(event))
{
Dialog dialog(NULL,-1,"Titre",Chiffre);
if ( dialog.ShowModal() == wxID_OK )
{
wxString st = "Aucun";
Chiffre = dialog.GetValue();
switch(Chiffre)
{
case 1 : st = "Un";
break;
case 2 : st = "Deux";
break;
case 3 : st = "Trois";
break;
}
Label->SetLabel("N° Sélectionné : " + st);
}
}

IV - Code source complet

IV-A - wxwin1.h

#ifndef wxWinH
#define wxWinH

class Application : public wxApp
{
public:
virtual bool OnInit();
};
//------------------------------------------------------------------------------
class Frame : public wxFrame
{
public:
Frame(const wxString& title, const wxPoint& pos, const wxSize& size,
long style = wxDEFAULT_FRAME_STYLE);
private:
int Chiffre; //mémorise le chiffre sélectionné
wxStaticText *Label;
void OnQuit(wxCommandEvent& event);
void OnDialog(wxCommandEvent& event);
DECLARE_EVENT_TABLE()
};
//------------------------------------------------------------------------------
class Dialog : public wxDialog
{
public:
Dialog(wxWindow* parent, wxWindowID id, const wxString& title, int nb = 0);
int GetValue();
void SetValue(int);
private:
wxRadioButton *RadioBouton1;
wxRadioButton *RadioBouton2;
wxRadioButton *RadioBouton3;
};
//------------------------------------------------------------------------------
enum
{
App_Quit = 1,
Menu_dialog
};

#endif //wxWinH

IV-B - wxwin1.cpp

#include "wx/wxprec.h"

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include "wx/wx.h"
#endif
//------------------------------------------------------------------------------
#include "wxWin.h"

BEGIN_EVENT_TABLE(Frame, wxFrame)
EVT_MENU(App_Quit,  Frame::OnQuit)
EVT_MENU(Menu_dialog,  Frame::OnDialog)
END_EVENT_TABLE()

IMPLEMENT_APP(Application)

bool Application::OnInit()
{
Frame *frame = new Frame("Frame", wxPoint(150, 150), wxSize(480, 220));
frame->Show();
return true;
}

//------------------------------------------------------------------------------
//LA FENÊTRE PRINCIPALE
//------------------------------------------------------------------------------
Frame::Frame(const wxString& title, const wxPoint& pos, const wxSize& size,
long style) : wxFrame(NULL, -1, title, pos, size, style)
{
SetIcon(wxICON(monicone));
etBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_BTNFACE));

wxMenu *menuFichier = new wxMenu;
menuFichier->Append(Menu_dialog,"Dialogue");
menuFichier->Append(App_Quit,"Quitter l'application");
wxMenuBar *menuBarre = new wxMenuBar();
menuBarre->Append(menuFichier,("&Fichier"));
SetMenuBar(menuBarre);

Label = new wxStaticText(this,-1,"N° Sélectionné : Aucun",wxDefaultPosition,
wxSize(-1, 60),wxALIGN_CENTRE | wxST_NO_AUTORESIZE );
Label->SetFont(wxFont(12, wxSWISS , wxNORMAL, wxBOLD, false, "Arial"));

wxBoxSizer *Psizer = new wxBoxSizer( wxVERTICAL );
Psizer->Add(-1,60);
Psizer->Add(Label,0, wxEXPAND );
SetSizer(Psizer);

Chiffre = 0;
}
//------------------------------------------------------------------------------
void Frame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
Close();
}
//------------------------------------------------------------------------------
void Frame::OnDialog(wxCommandEvent& WXUNUSED(event))
{
Dialog dialog(NULL,-1,"Titre",Chiffre);
if ( dialog.ShowModal() == wxID_OK )
{
wxString st = "Aucun";
Chiffre = dialog.GetValue();
switch(Chiffre)
{
case 1 : st = "Un";
break;
case 2 : st = "Deux";
break;
case 3 : st = "Trois";
break;
}
Label->SetLabel("N° Sélectionné : " + st);
}
}

//------------------------------------------------------------------------------
//LA BOÎTE DE DIALOGUE
//------------------------------------------------------------------------------
Dialog::Dialog(wxWindow* parent, wxWindowID id, const wxString& titre, int nb)
: wxDialog(parent,id,titre,wxDefaultPosition,wxSize(240, 200))
{
RadioBouton1 = new wxRadioButton(this,-1,"Un");
RadioBouton2 = new wxRadioButton(this,-1,"Deux");
RadioBouton3 = new wxRadioButton(this,-1,"Trois");
wxButton *MonBouton1 = new wxButton(this,wxID_OK,"Ok");
wxButton *MonBouton2 = new wxButton(this,wxID_CANCEL,"Annuler");

wxBoxSizer *sizer1 = new wxBoxSizer( wxVERTICAL );
sizer1->Add(-1,25);
sizer1->Add(RadioBouton1,0,wxALL,5);
sizer1->Add(RadioBouton2,0,wxALL,5);
sizer1->Add(RadioBouton3,0,wxALL,5);

wxBoxSizer *sizer2 = new wxBoxSizer( wxHORIZONTAL );
sizer2->Add(MonBouton1,0,wxBOTTOM | wxLEFT | wxRIGHT ,5);
sizer2->Add(MonBouton2,0,wxBOTTOM | wxLEFT | wxRIGHT ,5);

wxBoxSizer *Psizer = new wxBoxSizer( wxVERTICAL );
Psizer->Add(sizer1,3,wxALIGN_CENTER);
Psizer->Add(sizer2,1,wxALIGN_CENTER);
SetSizer(Psizer);
SetValue(nb);
}
//------------------------------------------------------------------------------
int Dialog::GetValue()
{
int x = 0;
if( RadioBouton1->GetValue() ) x = 1;
if( RadioBouton2->GetValue() ) x = 2;
if( RadioBouton3->GetValue() ) x = 3;
return x;
}
//------------------------------------------------------------------------------
void Dialog::SetValue(int x)
{
switch(x)
{
case 1 : RadioBouton1->SetValue(true);
break;
case 2 : RadioBouton2->SetValue(true);
break;
case 3 : RadioBouton3->SetValue(true);
break;
}
}

V - Remarques sur ce document

Nous avons pu voir dans cet article une des façons de construire une boîte de dialogue personnalisée avec wxWidgets. Il faut savoir qu'il existe plusieurs façons de faire : wxWidgets peut mettre en œuvre des fichiers ressources qui lui sont propres.

J'ai réalisé les compilations dans l'EDI de C++ Builder, wxWidgets étant installé comme vu dans l'article : « Installation de wxWidgets dans l'EDI de C++ Builder ».

Pour les autres compilateurs, veuillez vous référer à leur documentation respective ainsi qu'à la documentation de wxWidgets.

À bientôt,

CGi

Avec la contribution d'Anomaly pour la relecture.