Traduction par Jean-luc Biord, du Site de la communauté
Qt francophone.
English TOC.
Dans ce chapitre, nous commencerons à utiliser Qt, pour produire une application plus substantielle. Nous construirons un dialogue simple avec une liste à laquelle l'utilisateur pourra ajouter des items. Des items dans la liste pourront également être enlevés.
Le schéma 5-1 montre à ce que ressemblera l'application terminée. Pour concevoir le dialogue et écrire le code nous emploierons Qt Designer.
La première étape sera d'ouvrir un terminal et de créer un dossier. Je choisis de l'appeler ex05, mais n'importe quel nom peut être employé. Tapez cd pour entrer dans le nouveau dossier et démarrer Qt Designer en tapant designer & (ou designer-qt3 & dans quelques distributions). Il est possible de démarrer Qt Designer depuis les menus fournis dans des distributions modernes, mais nous allons lancer quelques commandes dans une console, et je vous recommande de procéder de cette façon. Cela vous amène (si tout va bien) à la fenêtre représentée sur le schéma 5-2.
Commençons en créant un nouveau projet C++. Choisissez simplement File - New. Sélectionnez "C++ project" et choisissez de continuer. Dans le dialogue suivant (schéma 5-3), saisissez un nom pour votre projet (utilisez le bouton "..." pour obtenir un dialogue de sélection de fichiers). Je choisis de l'appeler simple-dialog.pro. Il n'y a pas besoin de toucher aux autres onglets pour le moment, mais vous êtes libre de l'explorer avant de cliquer le bouton Ok.
Maintenant nous avons un projet, tout ce qui reste à faire est de mettre des choses dedans. Choisissez de nouveau File - New , mais cette fois, ajoutez un dialogue au projet. Vous finirez par avoir un dialogue vide appelé Form1. Nous commencerons par le renommer en quelque chose de mieux comme dlgMain. Cela se fait en changeant la propriété name dans l'éditeur de propriété habituellement montré sur le côté droit de la fenêtre principale de Qt Designer. Si vous ne pouvez pas la trouver, assurez-vous qu'elle est visible en vérifiant que le sous menu Windows - Views. property editor/signal handlers soit coché. (le préfixe dlg indique que nous traitons un dialogue. C'est un peu Microsofttien, mais j'estime qu'il clarifie des choses en réutilisant le code.)
NOTE! Vous devez nommer tous vos widgets, dialogues et fenêtres avant d'éditer le code correspondant si vous voulez éviter des confusions dans Qt Designer.
Le tableau 5-1 récapitule les changements faits aux propriétés du dialogue :
Widget | Propriété | Nouvelle Valeur |
dlgMain | Name | dlgMain |
dlgMain | Caption | Simple Dialog Example |
Maintenant nous sommes prêts pour commencer à ajouter des widgets au dialogue. Ajoutez un group box contenant une list box, une line edit et deux boutons. Au-dessous de la group box, ajoutez un autre bouton. Les widgets sont disponibles dans les barres d'outils et leurs noms sont montrés si le pointeur de la souris est maintenu au-dessus du bouton pendant un court instant.
Le schéma 5-4 montre les noms préférés et la place approximative des widgets sur le dialogue.
Le bouton au-dessous du group box est appelé pbOk. Les deux autres boutons sont nommés pbAdd et pbRemove. La list box est appelée lbItems, le line edit leItem. Le tableau 5-2 récapitule les changements faits à leurs propriétés.
Widget | propriété | Nouvelle Valeur |
pbAdd | Name | pbAdd |
pbAdd | Text | Add |
pbAdd | Default | True |
pbRemove | Name | pbRemove |
pbRemove | Text | Remove |
pbOk | Name | pbOk |
pbOk | Text | Ok |
lbItems | Name | lbItems |
leItem | Name | leItem |
GroupBox1 | Title | (empty) |
Pour tester le dialogue, choisissez un style que vous aimez dans le menu Preview (essayez plusieurs modèles et comparez-les). Le schéma 5-5 montre mon résultat dans le modèle Windows, mais ce que vous avez peut apparaitre complètement différement. L'important est que vous ayez les mêmes widgets dans le dialogue.
Je pense que tous nous pouvons convenir que c'est laid. Avant que vous ne commenciez à réarranger les widgets pour améliorer leur aspect nous devons discuter d'une spécificité de Qt. Qt est conçu pour fonctionner sur beaucoup de systèmes allant des palmtops jusqu'aux serveurs Unix. Il gère également des applications internationalisées avec le support de n'importe quelle langue imaginable. Pour rendre possible d'exécuter des applications Qt avec différents textes à la même place et dans toute résolution d'écran il y a une solution appelée layouts. Au lieu d'indiquer exactement où les widgets se trouvent, nous indiquons comment ils se trouvent les uns par rapport aux autres. Vous verrez bientôt ce que cela signifie.
Avant d'appliquer toutes les layouts nous devons ajouter des spacers pour remplir l'espace vide de notre dialogue. Le spacer est employé comme widget mais sera invisible au moment de l'exécution. Ils sont sélectionnés dans les barres d'outils et dessinés dans le dialogue exactement comme d'autres widgets. Sur le schéma 5-6 les deux spacers utilisés dans ce dialogue sont montrés.
Pour sélectionner plusieurs widgets simultanément, sélectionnez le premier, enfoncez alors la touche Majuscule tout en sélectionnant les autres. Sélectionnez maintenant le bouton Ok et le spacer à sa gauche. Cliquez alors sur "layout horizontally". Le schéma 5-7 montre les différents boutons layout comme montré dans la barre d'outils de Qt Designer (notez qu'ils sont bleu si actifs)..
Sélectionnez maintenant la line edit et les deux boutons dans le group box ainsi que le spacer et choisissez de les répartir verticalement.
Sélectionnez alors le group box entièrement et choisissez la disposition horizontale (ceci s'applique à tous les widgets à l'intérieur du group box).
Finalement, choisissez le dialogue suivi de la disposition verticale. Si vous faites n'importe quelles erreurs en appliquant les dispositions (layout), ou que vous vous sentiez expérimentateur, choisissez simplement une disposition et cliquez sur "break layout" afin de recommencer.
La prévisualisation devrait vous donner quelque chose comme le dialogue représenté sur le schéma 5-8. Changez la taille du dialogue pour examiner la flexibilité des dispositions. Imaginez seulement si toutes les boîtes de liste qui sont trop étroites dans les applications win32 pouvaient faire ceci!
Maintenant nous avons terminé la conception visuelle du dialogue. Il y a encore juste deux choses plus visuelles à faire avant que nous commencions l'écriture du code.
La première chose est de fixer l'ordre de tabulation, c.-à-d. l'ordre dans lequel les widgets sont activés quand la touche tabulation est employée pour se déplacer dans le dialogue. Cliquez simplement sur le bouton d'ordre de tabulation ("Tab Order" qui ressemble à trois lignes vertes avec 1, 2 et 3 à la gauche), cliquez alors les widgets dans l'ordre que vous voulez. Pour annuler le mode d'ordre de tabulation, cliquez la flèche dans le toolbar (le tooltip pour la flèche est Pointer).
Maintenant, regardez l'explorateur d'objet, habituellement au-dessus de l'éditeur de propriété. Activez l'onglet Members (appelée Source dans des versions plus anciennes de Qt) et ajoutez deux slots publics (cliquez droit sur la ligne public au-dessous de la ligne slots). Le schéma 5-9 montre les slots qui doivent être ajoutés. Souvenez-vous des parenthèses en déclarant chaque slot.
Maintenant, le temps est venu d'ajouter un peu de code. Fermez le dialogue en cliquant sur le bouton Ok, puis commencez en cliquant sur un des slots que vous venez juste de créer. Cela affichera une fenêtre de code avec le code montré dans l'exemple 5-1.
/****************************************************************************
** ui.h extension file, included from the uic-generated form
implementation.
**
** If you wish to add, delete or rename slots use Qt Designer which will
** update this file, preserving your code. Create an init() slot in
place of
** a constructor, and a destroy() slot in place of a destructor.
*****************************************************************************/
void dlgMain::addItem()
{
}
void dlgMain::removeItem()
{
}
Avant que nous commencions à modifier le code, nous ajouterons un dernier slot. Cette fois, ajoutons un slot protégé appelé init(). Ce slot sera automatiquement ajouté dans la fenêtre de source. C'est l'un de deux slots spéciaux ajoutés par Qt Designer pour éviter la vieille (version 2.x de Qt) approche quand il était nécessaire d'hériter chaque dialogue afin d'ajouter un constructeur ou un destructeur. Les slots protégés init() et destroy() économise cette approche. La conception est plus pragmatique que la vieille, et enlève un des inconvénients d'une interface trop propre.
Dans le slot addItem(), nous effectuons les actions qui doivent être faites quand l'utilisateur clique sur le bouton add. Ces actions doivent vérifier si le widget line edit contient du texte et si oui, l'ajouter à la liste, ensuite effacer le widget line edit et placer le focus courant sur lui de sorte que l'utilisateur puisse continuer de saisir.
Le slot removeItem() vérifie simplement si une ligne est sélectionnée dans le widget list box et si oui, la supprime.
Finalement, le slot init() s'assure que la list box est vide et puis place le focus dans le widget line edit.
En écrivant le code, vous noterez que dans la liste affichée Qt Designer énumère seulement les propriétés et les slots. Ainsi les méthodes que nous employons ne sont pas énumérées.
Le code final est montré dans l'exemple 5-2.
/****************************************************************************
** ui.h extension file, included from the uic-generated form
implementation.
**
** If you wish to add, delete or rename slots use Qt Designer which will
** update this file, preserving your code. Create an init() slot in
place of
** a constructor, and a destroy() slot in place of a destructor.
*****************************************************************************/
void dlgMain::addItem()
{
if( leItem->text().length() > 0 )
{
lbItems->insertItem( leItem->text() );
leItem->clear();
}
leItem->setFocus();
}
void dlgMain::removeItem()
{
if( lbItems->currentItem() > -1 )
lbItems->removeItem(
lbItems->currentItem() );
}
void dlgMain::init()
{
lbItems->clear();
leItem->setFocus();
}
Avant que nous puissions compiler cet exemple, nous devons ajouter une fonction main() à notre projet. C'est le mieux pour séparer le code en modules, et maintient ainsi le code de dlgMain dans ses propres fichiers. Ainsi nous ajoutons un nouveau fichier source C++ (Utiliser - New comme avant, mais ajoutez cette fois un fichier source C++).
Ajoutez le code de l'exemple 5-3 au fichier nouvellement créé et sauvez-le comme main.cpp. Lisez les commentaires pour comprendre comment cela fonctionne.
// Header for the QApplication class
#include <qapplication.h>
// Header for our dialog
#include "dlgmain.h"
// Remember the ( int, char** ) part as the
QApplication needs them
int main( int argc, char **argv )
{
// We must always have an application
QApplication a( argc, argv );
dlgMain *m = new dlgMain(); // We create our dialog
a.setMainWidget( m
); // It is our main widget
m->show(); // Show it...
return
a.exec(); // And run!
}
Maintenant nous sommes prêts à compiler le projet, mais d'abord nous devons créer un fichier Makefile. Veillez à tout sauvegarder dans Qt Designer (utilisez File - Save All) basculons alors dans une console et effectuons un cd pour nous rendre dans le répertoire du projet. Maintenant exécutons qmake sur le fichier projet .pro que Qt Designer a créé. Par exemple exécutez qmake simple-dialog.pro, puis exécutez make. Si tout le code est correct, le résultat sera un exécutable avec le même nom que le projet, c.-à-d. simple-dialogue, dans mon cas.
Si vous lancez l'exécutable produit par make, vous noterez qu'il semble correct, mais rien ne fonctionne. C'est parce que nous n'avons encore relié aucun signal à nos slots. Pour faire cela, basculez de nouveau vers Qt Designer, ou rouvrez-le si vous l'avez fermé.
Choisissez l'outil de connexion signals/slots (entre la flèche et l'outil d'ordre des tabulations). Puisse-que notre dialogue (dlgMain) et ses widgets contiennent les signaux et les slots que nous avons l'intention d'employer, nous pouvons relier visuellement les signaux des différents widgets aux slots appropriés . Cliquez simplement et tirez la souris depuis un widget bouton vers un endroit libre sur le dialogue (il s'entoure de couleur) et relachez le bouton de souris. Dans le dialogue qui apparaît, reliez le signal "clicked" de chaque bouton avec le slot approprié. Le signal pbAdd devrait être relié à addItem, pbRemove à removeItem et pbOk à close. Pour éviter d'avoir l'outil de connexion déselectionné après chaque connexion, vous pouvez double cliquer sur la barre d'outil la première fois que vous la choisissez.
Pour vérifier que les signaux et les slots sont correctement reliés, cliquez droit sur le dialogue et choisissez connections dans le menu popup qui apparaît. Le dialogue résultant devrait ressembler au schéma 5-10.
Maintenant, de retour dans la console, lançons make et essayons de lancer l'exécutable obtenu. Si tout est correct, il devrait fonctionner comme prévu!
En pressant la touche retour ou entrée dans le line edit, un bouton sera activé. Ce sujet a été discuté dans la mailing list qt-interest ici. Recherchez cette liste si vous avez n'importe quel problème, et souscrivez y. C'est vraiment intéressant.
Avant de terminer ce chapitre, je veux préciser l'architecture de cette application. Nous n'avons pas de boucle de message, ni aucun endroit d'où les choses sont commandées. Au lieu de cela nous instantions un dialogue, relions des événements aux slots et mettons les fonctionnalités dans les slots. C'est la programmation conduite par événement!
Le code d'exemple de ce chapitre peut être téléchargé ici.
Ce chapitre couvre l'approche de base de Designer. C'est la manière dont nous ferons la plupart des choses ce tutoriel.
This is a part of digitalfanatics.org and is valid XHTML.
Copyright (c) 2002-2004 by Johan Thelin (e8johan -at- digitalfanatics.org). This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 (local copy) or later (the latest version is presently available at http://www.opencontent.org/openpub/). Distribution of substantively modified versions of this document is prohibited without the explicit permission of the copyright holder. Distribution of the work or derivative of the work in any standard (paper) book form is prohibited unless prior permission is obtained from the copyright holder.