Deuxième Étape
Utilisations des contrôles
Ajouter des fonctionnalités à la fenêtre de base
Dans la session précédente, nous avons vu l'architecture de base de wxWindows et construit la plus simple des applications. Ce n'est pas beaucoup mais cela démontre les fonctionnalités de base d'un programme typique Windows.
La prochaine étape est d'ajouter quelques fonctionnalités supplémentaires afin que nous puissions développer quelque chose d'une utilité moins évidente mais plus important pour l'apprentissage à propos du cadre de travail wxWindows.
Dans cette session nous allons ajouter un contrôle de texte, un menu et une barre d'état à notre BasicFrame. La première étape est d'ajouter un contrôle de texte.
Ajouter un contrôle de texte
|
L'application avec un contrôle de texte est montrée ici. Le contrôle de texte fournit les fonctionnalités d'un éditeur de texte c.a.d:
- mouvement de curseur,
- insertion de texte, sélection et suppression,
- couper, copier, coller.
|
Avec quelques programmations assez simples, ajoutons de quoi :
- ouvrir un fichier, enregistrer et enregistrer sous,
- annuler et rétablir des opérations,
- changer de polices de caractères.
Le style de base wxTextCtrl est juste le contrôle d'une seule ligne de texte qui vous permet d'utiliser une boite de dialogue pour assembler les données utilisateurs de votre programme. Changer le contrôle de texte vers quelque chose qui va saisir beaucoup de lignes est simplement un critère de changement de style. De plus, changer le contrôle de texte vers quelque chose qui va saisir une grande quantité de données est aussi accompli par un changement de style.
Voici le code source pour notre BasicFrame avec un contrôle de texte.
#ifndef BASIC_H
#define BASIC_H
class BasicApplication : public wxApp
{
public:
virtual bool OnInit();
};
class BasicFrame : public wxFrame
{
public:
BasicFrame( const wxChar *title,
int xpos, int ypos,
int width, int height);
~BasicFrame();
wxTextCtrl *theText;
};
#endif |
Le fichier d'en-tête est presque inchangé excepté pour la ligne:
wxTextCtrl *theText;
Là, nous déclarons un pointeur vers un contrôle de texte wxTextCtrl nommé the Text . |
#include <wx/wx.h>
#include "basic.h"
IMPLEMENT_APP(BasicApplication)
bool BasicApplication::OnInit()
{
BasicFrame *frame
= new BasicFrame
("wxWindows Basic Steps - Step 1:"
" A simple application",
50, 50, 200, 200);
frame->Show(TRUE);
SetTopWindow(frame);
return TRUE;
}
BasicFrame::BasicFrame
(const wxChar *title,
int xpos, int ypos,
int width, int height)
: wxFrame( (wxFrame *) NULL,
-1, title,
wxPoint(xpos, ypos),
wxSize(width, height))
{
theText = (wxTextCtrl *) NULL;
theText
= new wxTextCtrl
( this,
-1,
wxString("This is a text control\n\n"
"The text control supports"
" basic text editing operations\n"
"along with copy, cut, paste, "
"delete, select all and undo.\n\n"
"Right click on the control"
" to see the pop-up menu.\n"
),
wxDefaultPosition,
wxDefaultSize,
wxTE_MULTILINE
);
}
BasicFrame::~BasicFrame()
{
} |
Comme la complexité des programmes augmente vous aurez très souvent à déclarer des pointeurs vers des objets qui n'existent pas encore. Quelquefois vous tomberez dans le piège d'utiliser un de ces pointeurs avant que vous ayez réellement créé l'instance de la classe vers laquelle vous voulez pointer. Le résultat de l'utilisation d'un pointeur non déclaré peut passer de gentiment irritant à franchement frustrant. Vous pourriez perdre juste quelques secondes de votre temps si précieux ou bien quelques heures ! .
Ce qui va de soi est que vous devez toujours initialiser tous les pointeurs que vous avez déclarés dans un fichier d'interface. D'autres personnes vous diront “Ce n'est pas un problème, j'ai l'intention d'initialiser cela un beau jour.
Je dis « ignorer les » et vous empêcherez les erreurs d'une telle démarche existentielle avec les « mauvais » pointeurs. Je dis ceci en dehors de toute préoccupation de bien-être fraternel.
L'appel au constructeur du contrôle de texte
theText = new wxTextCtrl( ... )
contient un paramètre this qui est une référence à la fenêtre parent . Dans ce cas this pointe vers le cadre parent qui est en train d'être ou qui vient juste d'être construit. |
La classe de contrôle de texte – wxTextCtrl
Le constructeur wxTextCtrl |
|
wxTextCtrl ( wxWindow* parent, wxWindowID id, const wxString& value = "", const wxPoint& pos, const wxSize& size = wxDefaultSize, long style = 0, const wxValidator& validator, const wxString& name = "text" ) |
Si vous comparez le constructeur présenté ici avec l'exemple, vous verrez que j'ai utilisé un nombre par défaut , comme je l'ai déjà fait avec BasicFrame de la session précédente.
Le constructeur wxTextCtrl indique le même type de modèle que beaucoup de contrôle wxWindows et c'est la grande force du cadre de travail wxWindows . Beaucoup des nouvelles choses que vous apprendrez à propos de ce cadre de travail, par exemple le modèle de déclaration du constructeur, peut être utilisé comme gabarit partout ailleurs dans ce cadre de travail. |
Vous avez vu le constructeur wxFrame, et pu voir que le constructeur wxTextCtrl est très semblable à la fois dans l'ordre des paramètres et des types de paramètres qu'ils utilisent . wxTextCtrl introduit un nouveau paramètre qui s'applique uniquement au texte: la classe wxValidator. Je ne vais pas vous décrire les détails de cette classe maintenant, cela est quelque peu complexe. Assez pour vous dire que nous pouvons utiliser le « validator » pour valider les données qui sont transmises depuis le(s) contrôle(s) vers la structure de données du programme. Vous pouvez utiliser un « validator » pour limiter les entrées à du texte seulement ou bien des données numériques.
Les paramètres à retenir pour le constructeur wxTextCtrl sont les mêmes que pour wxFrame:
- wxWindow* parent – un pointeur vers la fenêtre parent, MAIS il ne peut être NULL, alors que le cadre (frame) lui peut.
- wxWindowID id - un ID pour le contrôle .
- const wxString& value = "" – une valeur initiale (voir l'exemple).
- const wxPoint& pos – La position x et y du coin en haut à gauche,
- const wxSize& size = wxDefaultSize –Les dimensions : largeur et hauteur,
- long style = 0 - Le style (voir ci-dessous),
- const wxString& name = "text" - un nom pour le contrôle.
Les styles de fenêtres wxTextCtrl :
wxTE_PROCESS_ENTER - Le contrôle générera le message. wxEVENT_TYPE_TEXT_ENTER_COMMAND Les autres touches sont d'autre part traitées intérieurement par le contrôle ou utilisé pour la navigation entre les contrôles du dialogue.
- wxTE_PROCESS_TAB - Le contrôle recevra les messages EVT_CHAR pour la touche TAB - normalement, TAB est utilisé pour passer au contrôle suivant au lieu de d'être dans un dialogue. Pour le contrôle crée avec ce style, vous pouvez encore utiliser Ctrl-Enter pour passer au contrôle suivant à partir du clavier.
- wxTE_MULTILINE - Un (véritable) contrôle de texte qui permet les lignes multiples.
- wxTE_PASSWORD - Le texte sera restitué sous forme d'astérisque.
- wxTE_READONLY - Le texte ne sera pas éditable.
- wxHSCROLL – Une barre de défilement horizontal sera crée. Pas d'effet sous GTK+.
Et à cela, nous pouvons ajouter:
- wxTE_RICH - qui évolue en un véritable contrôle de texte, qui a une limite d'environ 32K de données, en un contrôle de texte enrichi qui peut fournir d'abondantes connaissances sur bien des données. C'est pour Windows 95/98 seulement et est ignoré sur les autres plate-formes (pour WinNT il n'y a pas de limite pour le véritable contrôle de texte multiple ligne, wxTE_MULTILINE).
Un style de contrôle texte, comme un style de cadre (frame), est le OU un à plusieurs styles, bien que le style par défaut est 0, indiquant que vous pouvez saisir une seule ligne de texte sans se préoccuper comment sont les dimensions en largeur et hauteur.
Vous pouvez essayer les styles de wxTextCtrl juste pour se faire une idée de ce que vous pouvez ou non combiner, par exemple pouvez-vous combiner wxTE_MULTILINE | wxTE_PASSWORD?
( Commentaire_2_b)
Pour construire le programme:
Créer les fichiers source dans un répertoire :
- basic.h
- basic.cpp
- basic_resources.rc
- Makefile
Exécuter make dans ce répertoire
Exécuter le programme basic
Ajouter une barre de menus
Bien qu'avec les contrôles de cadre et de texte nous ayons suffisamment fourni de fonctions à nos programmes, nous avons encore un certain nombre d'étapes à franchir avant d'avoir quelque chose proche d'une véritable application. La nouvelle chose à ajouter est une barre de menus afin que nous puissions préparer nos utilisateurs à découvrir d'autres commandes dans notre programme.
#ifndef BASIC_H
#define BASIC_H
enum
{ BASIC_EXIT = 1,
BASIC_OPEN = 100,
BASIC_ABOUT = 200
};
class BasicApplication : public wxApp
{
...
};
class BasicFrame : public wxFrame
{
public:
BasicFrame( ... );
~BasicFrame();
wxTextCtrl *theText;
wxMenuBar *menuBar;
wxMenu *fileMenu;
};
#endif |
Le fichier d'en-têtes est substantiellement le même excepté cet ajout:
enum
{ BASIC_EXIT = 1,
BASIC_OPEN = 100,
BASIC_ABOUT = 200
};
Noter que j'ai coupé quelques morceaux (indiqué avec les petits points ...) puisqu'ils sont inchangés.
L'« enum »déclare quelques valeurs que nous utiliserons pour l'associer avec un menu.
Les lignes suivantes:
wxMenuBar *menuBar;
wxMenu *fileMenu;
déclare que la classe BasicFrame a deux nouveaux membres. L'un est une barre de menu, l'autre un menu. La barre de menu bien sûr est la pièce située en haut du cadre. Le menu est un menu déroulant vers le bas. |
#include <wx/wx.h>
#include "basic.h"
IMPLEMENT_APP(BasicApplication)
bool BasicApplication::OnInit()
{ ...
return TRUE;
}
BasicFrame::BasicFrame
( ... )
{
theText = (wxTextCtrl *) NULL;
menuBar = (wxMenuBar *) NULL;
fileMenu = (wxMenu *) NULL;
theText = new wxTextCtrl( ... );
fileMenu = new wxMenu;
fileMenu->Append(BASIC_OPEN, "&Open file");
fileMenu->Append(BASIC_ABOUT, "&About");
fileMenu->AppendSeparator();
fileMenu->Append(BASIC_EXIT, "E&xit");
menuBar = new wxMenuBar;
menuBar->Append(fileMenu, "&File");
SetMenuBar(menuBar);
}
BasicFrame::~BasicFrame()
... |
Les ajouts au fichier d'implémentation sont indiqués ici. La sécurité passe encore avant tout:
menuBar = (wxMenuBar *) NULL;
fileMenu = (wxMenu *) NULL;
Nous avons crée une instance de wxMenu
fileMenu = new wxMenu;
Nous utilisons les méthodes Append() et AppendSeparator() pour ajouter des items au nouveau « fileMenu »:
fileMenu->Append(BASIC_OPEN, "&Open file");
fileMenu->Append(BASIC_ABOUT, "&About");
fileMenu->AppendSeparator();
fileMenu->Append(BASIC_EXIT, "E&xit");
Enfin nous avons crée une instance de wxMenuBar, adjoint le menu fichier &File et appelé la méthode SetMenuBar() pour ajouter la barre de menu à notre cadre : ( commentaire_3 )
menuBar = new wxMenuBar;
menuBar->Append(fileMenu, "&File");
SetMenuBar(menuBar); |
Noter comment le « et » commercial & est utilisé dans la chaîne comme "E&xit" et "&File". Cela indique quel caractère dans la barre de menus ou le menu est la touche de raccourci clavier.
Vous devez penser que notre barre de menu ne fait pas grand-chose dés lors que, lorsqu'elle s'affiche, on clique dessus ou bien on appuie sur ALT- ?. Cela sera bientôt abordé, dés que nous aurons vu les événements(events).Dans l'intervalle, nous allons ajouter une barre d'état.
Pour construire le programme:
Créer les fichiers source dans un répertoire :
- basic.h
- basic.cpp
- basic_resources.rc
- Makefile
Exécuter make dans ce répertoire:
- make
- Exécuter le programme basic
Vous pouvez télécharger les fichiers (wxbasic2.zip) si vous le souhaitez.
Ajouter une barre d'état
Ajouter une barre d'état ne peut être plus simple. Ajouter la ligne « CreateStatusBar(3);” :
SetMenuBar(menuBar);
CreateStatusBar(3);
Cela va ajouter une barre d'état contenant 3 champs à notre cadre. Nous ajouterons une valeur de chaîne à un champs avec la méthode SetStatusBarText("string", integer) de wxFrame. « Integer” est 0, 1 or 2 dans le cas d'une barre d'état à 3 champs.
Si vous faites un petit changement à l'exemple précédent, c'est à dire ajouter un 3 ème paramètre à la méthode Append():
fileMenu->Append(BASIC_OPEN, "&Open file", "Open an existing file");
fileMenu->Append(BASIC_ABOUT, "&About", "Who wrote this!");
fileMenu->AppendSeparator();
fileMenu->Append(BASIC_EXIT, "E&xit", "Stop wasting time.");
vous verrez le 3 ème paramètre s'afficher dans le champ 0 de la barre d'état.
Les classes wxWindows que nous utilisons
Nous n'avons utiliser que deux classes wxMenuBar et wxMenu, et la méthode CreateStatusBar() de wxFrame qui nous a permis de créer, positionner, .., notre barre d'état.
Je reviendrais sur les classes wxMenuBar et wxMenu plus tard, la nouvelle chose dont nous avons besoin, c'est de voir comment nous allons construire un programme qui répond aux choix du menu.
Sommaire
Quelque chose à faire... |
Prenez l'exemple facile de cette session et ajouter-y d'autres menus.
Pourquoi dois-je ajouter des lignes comme?
theText = (wxTextCtrl *) NULL;
Quelle est la différence entre:
frame->Show(TRUE);
et
frame.Show(TRUE); ? |
Dans cette session, nous avons complété notre application Basic en y joignant quelques fonctionnalités de fenêtres courantes. La chose intéressante fût le peu d'efforts accomplis. C'est le signe d'un cadre de travail bien conçu.
Nous avons vu aussi avec quelle simplicité nous avons modifier le style du contrôle de texte et bénéficié de la flexibilité induite par la classe wxMenu.
Retour en début de document