source: trunk/doc/src/tutorials/addressbook-fr.qdoc@ 321

Last change on this file since 321 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 49.1 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the documentation of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/*!
43 \page tutorials-addressbook-fr.html
44
45 \startpage {index.html}{Qt Reference Documentation}
46 \nextpage {tutorials/addressbook-fr/part1}{Chapitre 1}
47
48 \title Tutoriel "Carnet d'adresses"
49 \ingroup howto
50 \ingroup tutorials
51 \brief Une introduction à la programation d'interface graphique montrant comment construire une application simple avec Qt.
52
53 Ce tutoriel est une introduction à la programmation de GUI (interface utilisateur)
54 à l'aide des outils fournis par la plateforme multiplate-forme Qt.
55
56 \image addressbook-tutorial-screenshot.png
57
58 Ce tutoriel va nous amener à découvrir quelques technologies fondamentales fournies
59 par Qt, tel que:
60
61 \list
62 \o Les Widgets et leur mise en page à l'aide des layouts
63 \o Les signaux et slots
64 \o Les structures de données de collections
65 \o Les entrées/sorties
66 \endlist
67
68 Si c'est votre premier contact avec Qt, lisez \l{How to Learn Qt}{Comment apprendre Qt}
69 si ce n'est déjà fait.
70
71 Le code source du tutoriel est distribué avec Qt dans le dossier \c examples/tutorials/addressbook
72
73 Les chapitres du tutoriel:
74
75 \list 1
76 \o \l{tutorials/addressbook-fr/part1}{Conception de l'interface utilisateur}
77 \o \l{tutorials/addressbook-fr/part2}{Ajouter des adresses}
78 \o \l{tutorials/addressbook-fr/part3}{Navigation entre les éléments}
79 \o \l{tutorials/addressbook-fr/part4}{éditer et supprimer des adresses}
80 \o \l{tutorials/addressbook-fr/part5}{Ajout d'une fonction de recherche}
81 \o \l{tutorials/addressbook-fr/part6}{Sauvegarde et chargement}
82 \o \l{tutorials/addressbook-fr/part7}{Fonctionnalités avancées}
83 \endlist
84
85 La petite application que nous développerons ici ne possède pas tous les éléments
86 des interfaces dernier cri, elle va nous permettre d'utiliser les techniques de base
87 utilisées dans les applications plus complexes.
88
89 Lorsque vous aurez terminé ce tutoriel, nous vous recommandons de poursuivre avec l'exemple
90 "\l{mainwindows/application}{Application}", qui présente une interface simple utilisant
91 les menus et barres d'outils, la barre d'état, etc.
92
93*/
94
95/*!
96 \page tutorials-addressbook-fr-part1.html
97 \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
98 \nextpage {tutorials/addressbook-fr/part2}{Chapitre 2}
99 \example tutorials/addressbook-fr/part1
100 \title Carnet d'adresses 1 - Conception de l'interface utilisateur
101
102 La première partie de ce tutoriel traite de la conception d'une interface graphique
103 (GUI) basique, que l'on utilisera pour l'application Carnet d'adresses.
104
105 La première étape dans la création d'applications graphiques est la conception de
106 l'interface utilisateur. Dans ce chapitre, nous verrons comment créer les labels
107 et champs de saisie nécessaires à l'implementation d'un carnet d'adresses de base.
108 Le résultat attendu est illustré par la capture d'écran ci-dessous.
109
110 \image addressbook-tutorial-part1-screenshot.png
111
112 Nous allons avoir besoin de deux objets QLabel, \c nameLabel et \c addressLabel,
113 ainsi que deux champs de saisie: un objet QLineEdit, \c nameLine, et un objet
114 QTextEdit, \c addressText, afin de permettre à l'utilisateur d'entrer le nom d'un
115 contact et son adresse. Les widgets utilisés ainsi que leur placement sont visibles ci-dessous.
116
117 \image addressbook-tutorial-part1-labeled-screenshot.png
118
119 Trois fichiers sont nécessaires à l'implémentation de ce carnet d'adresses:
120
121 \list
122 \o \c{addressbook.h} - le fichier de définition (header) pour la classe \c AddressBook,
123 \o \c{addressbook.cpp} - le fichier source, qui comprend l'implémentation de la classe
124 \c AddressBook
125 \o \c{main.cpp} - le fichier qui contient la méthode \c main() , et
126 une instance de la classe \c AddressBook.
127 \endlist
128
129 \section1 Programmation en Qt - héritage
130
131
132 Lorsque l'on écrit des programmes avec Qt, on a généralement recours à
133 l'héritage depuis des objets Qt, afin d'y ajouter des fonctionnalités.
134 C'est l'un des concepts fondamentaux de la création de widgets personnalisés
135 ou de collections de widgets. Utiliser l'héritage afin de compléter
136 ou modifier le comportement d'un widget présente les avantages suivants:
137
138 \list
139 \o La possibilité d'implémenter des méthodes virtuelles et des méthodes
140 virtuelles pures pour obtenir exactement ce que l'on souhaite, avec la possibilité
141 d'utiliser l'implémentation de la classe mère si besoin est.
142 \o Cela permet l'encapsulation partielle de l'interface utilisateur dans une classe,
143 afin que les autres parties de l'application n'aient pas à se soucier de chacun des
144 widgets qui forment l'interface utilisateur.
145 \o La classe fille peut être utilisée pour créer de nombreux widgets personnalisés
146 dans une même application ou bibliothèque, et le code de la classe fille peut être
147 réutilisé dans d'autres projets
148 \endlist
149
150 Comme Qt ne fournit pas de widget standard pour un carnet d'adresses, nous
151 partirons d'une classe de widget Qt standard et y ajouterons des fonctionnalités.
152 La classe \c AddressBook crée dans ce tutoriel peut être réutilisée si on a besoin d'un
153 widget carnet d'adresses basique.
154
155
156 \section1 La classe AddressBook
157
158 Le fichier \l{tutorials/addressbook-fr/part1/addressbook.h}{\c addressbook.h} permet de
159 définir la classe \c AddressBook.
160
161 On commence par définir \c AddressBook comme une classe fille de QWidget et déclarer
162 un constructeur. On utilise également la macro Q_OBJECT pour indiquer que la classe
163 exploite les fonctionnalités de signaux et slots offertes par Qt ainsi que
164 l'internationalisation, bien que nous ne les utilisions pas à ce stade.
165
166 \snippet tutorials/addressbook-fr/part1/addressbook.h class definition
167
168 La classe contient les déclarations de \c nameLine et \c addressText,
169 les instances privées de QLineEdit et QTextEdit mentionnées précédemment.
170 Vous verrez, dans les chapitres à venir que les informations contenues
171 dans \c nameLine et \c addressText sont nécessaires à de nombreuses méthodes
172 du carnet d'adresses.
173
174 Il n'est pas nécessaire de déclarer les objets QLabel que nous allons utiliser
175 puisque nous n'aurons pas besoin d'y faire référence après leur création.
176 La façon dont Qt gère la parenté des objets est traitée dans la section suivante.
177
178 La macro Q_OBJECT implémente des fonctionnalités parmi les plus avancées de Qt.
179 Pour le moment, il est bon de voir la macro Q_OBJECT comme un raccourci nous
180 permettant d'utiliser les méthodes \l{QObject::}{tr()} et \l{QObject::}{connect()}.
181
182 Nous en avons maintenant terminé avec le fichier \c addressbook.h et allons
183 passer à l'implémentation du fichier \c addressbook.cpp.
184
185 \section1 Implémentation de la classe AddressBook
186
187 Le constructeur de la classe \c{AddressBook} prend en paramètre un QWidget, \e parent.
188 Par convention, on passe ce paramètre au constructeur de la classe mère.
189 Ce concept de parenté, où un parent peut avoir un ou plusieurs enfants, est utile
190 pour regrouper les Widgets avec Qt. Par exemple, si vous détruisez le parent,
191 tous ses enfants seront détruits égalament.
192
193
194 \snippet tutorials/addressbook/part1/addressbook.cpp constructor and input fields
195
196 à l'intérieur de ce constructeur, on déclare et instancie deux objets locaux
197 QLabel, \c nameLabel et \c addressLabel, de même on instancie \c nameLine et
198 \c addressText. La méthode \l{QObject::tr()}{tr()} renvoie une version traduite
199 de la chaîne de caractères, si elle existe; dans le cas contraire, elle renvoie
200 la chaîne elle même. On peut voir cette méthode comme un marqueur \tt{<insérer
201 la traduction ici>}, permettant de repérer les objets QString à considérer
202 pour traduire une application. Vous remarquerez, dans les chapitres à venir
203 comme dans les \l{Qt Examples}{exemples Qt}, qu'elle est utilisée chaque fois
204 que l'on utilise une chaîne susceptible d'être traduite.
205
206 Lorsque l'on programme avec Qt, il est utile de savoir comment fonctionnent les
207 agencements ou layouts. Qt fournit trois classes principales de layouts pour
208 contrôler le placement des widgets: QHBoxLayout, QVBoxLayout et QGridLayout.
209
210 \image addressbook-tutorial-part1-labeled-layout.png
211
212 On utilise un QGridLayout pour positionner nos labels et champs de saisie de manière
213 structurée. QGridLayout divise l'espace disponible en une grille, et place les
214 widgets dans les cellules que l'on spécifie par les numéros de ligne et de colonne.
215 Le diagramme ci-dessus présente les cellules et la position des widgets, et cette
216 organisation est obtenue à l'aide du code suivant:
217
218 \snippet tutorials/addressbook/part1/addressbook.cpp layout
219
220 On remarque que le label \c AddressLabel est positionné en utilisant Qt::AlignTop
221 comme argument optionnel. Ceci est destiné à assurer qu'il ne sera pas centré
222 verticalement dans la cellule (1,0). Pour un aperçu rapide des layouts de Qt,
223 consultez la section \l{Layout Classes}.
224
225 Afin d'installer l'objet layout dans un widget, il faut appeler la méthode
226 \l{QWidget::setLayout()}{setLayout()} du widget en question:
227
228 \snippet tutorials/addressbook/part1/addressbook.cpp setting the layout
229
230 Enfin, on initialise le titre du widget à "Simple Address Book"
231
232 \section1 Exécution de l'application
233
234 Un fichier séparé, \c main.cpp, est utilisé pour la méthode \c main(). Dans cette
235 fonction, on crée une instance de QApplication, \c app. QApplication se charge de
236 des ressources communes à l'ensemble de l'application, tel que les polices de
237 caractères et le curseur par défaut, ainsi que de l'exécution de la boucle d'évènements.
238 De ce fait, il y a toujours un objet QApplication dans toute application graphique en Qt.
239
240 \snippet tutorials/addressbook/part1/main.cpp main function
241
242 On construit un nouveau widget \c AddressBook sur le tas en utilisant le mot-clé
243 \c new et en invoquant sa méthode \l{QWidget::show()}{show()} pour l'afficher.
244 Cependant, le widget ne sera pas visible tant que la boucle d'évènements
245 n'aura pas été lancée. On démarre la boucle d'évènements en appelant la
246 méthode \l{QApplication::}{exec()} de l'application; le résultat renvoyé
247 par cette méthode est lui même utilisé comme valeur de retour pour la méthode
248 \c main().
249*/
250
251/*!
252 \page tutorials-addressbook-fr-part2.html
253 \previouspage {tutorials/addressbook-fr/part1}{Chapitre 1}
254 \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
255 \nextpage {tutorials/addressbook-fr/part3}{Chapitre 3}
256 \example tutorials/addressbook-fr/part2
257 \title Carnet d'adresses 2 - Ajouter des adresses
258
259 La prochaine étape pour créer notre carnet d'adresses est d'ajouter un soupçon
260 d'interactivité.
261
262 \image addressbook-tutorial-part2-add-contact.png
263
264 Nous allons fournir un bouton que l'utilisateur peut
265 cliquer pour ajouter un nouveau contact. Une structure de données est aussi
266 nécessaire afin de pouvoir stocker les contacts en mémoire.
267
268 \section1 Définition de la classe AddressBook
269
270 Maintenant que nous avons mis en place les labels et les champs de saisie,
271 nous ajoutons les boutons pour compléter le processus d'ajout d'un contact.
272 Cela veut dire que notre fichier \c addressbook.h a maintenant trois
273 objets QPushButton et trois slots publics correspondant.
274
275 \snippet tutorials/addressbook/part2/addressbook.h slots
276
277 Un slot est une méthode qui répond à un signal. Nous allons
278 voir ce concept en détail lorsque nous implémenterons la classe \c{AddressBook}.
279 Pour une explication détaillée du concept de signal et slot, vous pouvez
280 vous référer au document \l{Signals and Slots}.
281
282 Les trois objets QPushButton \c addButton, \c submitButton et \c cancelButton
283 sont maintenant inclus dans la déclaration des variables privées, avec
284 \c nameLine et \c addressText du chapitre précédent.
285
286 \snippet tutorials/addressbook/part2/addressbook.h pushbutton declaration
287
288 Nous avons besoin d'un conteneur pour stocker les contacts du carnet
289 d'adresses, de façon à pouvoir les énumérer et les afficher.
290 Un objet QMap, \c contacts, est utilisé pour ça, car il permet de stocker
291 des paires clé-valeur: le nom du contact est la \e{clé} et l'adresse du contact
292 est la \e{valeur}.
293
294 \snippet tutorials/addressbook/part2/addressbook.h remaining private variables
295
296 Nous déclarons aussi deux objects QString privés: \c oldName et \c oldAddress.
297 Ces objets sont nécessaires pour conserver le nom et l'adresse du dernier contact
298 affiché avant que l'utilisateur ne clique sur le bouton "Add". Grâce à ces variables
299 si l'utilisateur clique sur "Cancel", il est possible de revenir
300 à l'affichage du dernier contact.
301
302 \section1 Implémentation de la classe AddressBook
303
304 Dans le constructeur de \c AddressBook, \c nameLine et
305 \c addressText sont mis en mode lecture seule, de façon à autoriser l'affichage
306 mais pas la modification du contact courant.
307
308 \dots
309 \snippet tutorials/addressbook/part2/addressbook.cpp setting readonly 1
310 \dots
311 \snippet tutorials/addressbook/part2/addressbook.cpp setting readonly 2
312
313 Ensuite, nous instancions les boutons \c addButton, \c submitButton, et
314 \c cancelButton.
315
316 \snippet tutorials/addressbook/part2/addressbook.cpp pushbutton declaration
317
318 Le bouton \c addButton est affiché en invoquant la méthode \l{QPushButton::show()}
319 {show()}, tandis que \c submitButton et \c cancelButton sont cachés en invoquant
320 \l{QPushButton::hide()}{hide()}. Ces deux boutons ne seront affichés que lorsque
321 l'utilisateur cliquera sur "Add", et ceci est géré par la méthode \c addContact()
322 décrite plus loin.
323
324 \snippet tutorials/addressbook/part2/addressbook.cpp connecting signals and slots
325
326 Nous connectons le signal \l{QPushButton::clicked()}{clicked()} de chaque bouton
327 au slot qui gèrera l'action.
328 L'image ci-dessous illustre ceci:
329
330 \image addressbook-tutorial-part2-signals-and-slots.png
331
332 Ensuite, nous arrangeons proprement les boutons sur la droite du widget
333 AddressBook, et nous utilisons un QVBoxLayout pour les aligner verticalement.
334
335 \snippet tutorials/addressbook/part2/addressbook.cpp vertical layout
336
337 La methode \l{QBoxLayout::addStretch()}{addStretch()} est utilisée pour
338 assurer que les boutons ne sont pas répartis uniformément, mais regroupés
339 dans la partie supperieure du widget. La figure ci-dessous montre la différence
340 si \l{QBoxLayout::addStretch()}{addStretch()} est utilisé ou pas.
341
342 \image addressbook-tutorial-part2-stretch-effects.png
343
344 Ensuite nous ajoutons \c buttonLayout1 à \c mainLayout, en utilisant
345 \l{QGridLayout::addLayout()}{addLayout()}. Ceci nous permet d'imbriquer les
346 mises en page puisque \c buttonLayout1 est maintenant un enfant de \c mainLayout.
347
348 \snippet tutorials/addressbook/part2/addressbook.cpp grid layout
349
350 Les coordonnées du layout global ressemblent maintenant à ça:
351
352 \image addressbook-tutorial-part2-labeled-layout.png
353
354 Dans la méthode \c addContact(), nous stockons les détails du dernier
355 contact affiché dans \c oldName et \c oldAddress. Ensuite, nous
356 vidons ces champs de saisie et nous désactivons le mode
357 lecture seule. Le focus est placé sur \c nameLine et on affiche
358 \c submitButton et \c cancelButton.
359
360 \snippet tutorials/addressbook/part2/addressbook.cpp addContact
361
362 La méthode \c submitContact() peut être divisée en trois parties:
363
364 \list 1
365 \o Nous extrayons les détails du contact depuis \c nameLine et \c addressText
366 et les stockons dans des objets QString. Nous les validons pour s'assurer
367 que l'utilisateur n'a pas cliqué sur "Add" avec des champs de saisie
368 vides; sinon un message est affiché avec QMessageBox pour rappeller à
369 l'utilisateur que les deux champs doivent être complétés.
370
371 \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part1
372
373 \o Ensuite, nous vérifions si le contact existe déjà. Si aucun contacts
374 existant n'entre en conflit avec le nouveau, nous l'ajoutons à
375 \c contacts et nous affichons un QMessageBox pour informer l'utilisateur
376 que le contact a été ajouté.
377
378 \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part2
379
380 Si le contact existe déjà, nous affichons un QMessageBox pour informer
381 l'utilisateur du problème.
382 Notre objet \c contacts est basé sur des paires clé-valeur formés par
383 le nom et l'adresse, nous voulons nous assurer que la \e clé est unique.
384
385 \o Une fois que les deux vérifications précédentes ont été traitées,
386 nous restaurons les boutons à leur état normal à l'aide du code
387 suivant:
388
389 \snippet tutorials/addressbook/part2/addressbook.cpp submitContact part3
390
391 \endlist
392
393 La capture d'écran ci-dessous montre l'affichage fournit par un objet
394 QMessageBox, utilisé ici pour afficher un message d'information
395 à l'utilisateur:
396
397 \image addressbook-tutorial-part2-add-successful.png
398
399 La méthode \c cancel() restaure les détails du dernier contact, active
400 \c addButton, et cache \c submitButton et \c cancelButton.
401
402 \snippet tutorials/addressbook/part2/addressbook.cpp cancel
403
404 L'idée générale pour augmenter la flexibilité lors de l'ajout d'un
405 contact est de donner la possiblité de cliquer sur "Add"
406 ou "Cancel" à n'importe quel moment.
407 L'organigramme ci-dessous reprend l'ensemble des interactions dévelopées
408 jusqu'ici:
409
410 \image addressbook-tutorial-part2-add-flowchart.png
411*/
412
413/*!
414 \page tutorials-addressbook-fr-part3.html
415 \previouspage {tutorials/addressbook-fr/part2}{Chapitre 2}
416 \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
417 \nextpage {tutorials/addressbook-fr/part4}{Chapitre 4}
418 \example tutorials/addressbook-fr/part3
419 \title Carnet d'adresses 3 - Navigation entre les éléments
420
421 L'application "Carnet d'adresses" est maintenant à moitié terminée. Il
422 nous faut maintenant ajouter quelques fonctions pour naviguer entre
423 les contacts. Avant de commencer, il faut se décider sur le type de structure de
424 données le plus approprié pour stocker les contacts.
425
426 Dans le chapitre 2, nous avons utilisé un QMap utilisant des paires clé-valeur,
427 avec le nom du contact comme \e clé, et l'adresse du contact comme \e valeur.
428 Cela fonctionnait bien jusqu'ici, mais pour ajouter la navigation entre les
429 entrées, quelques améliorations sont nécessaires.
430
431 Nous améliorerons le QMap en le faisant ressembler à une structure de données
432 similaire à une liste liée, où tous les éléments sont connectés, y compris
433 le premier et le dernier élément. La figure ci-dessous illustre cette structure
434 de donnée.
435
436 \image addressbook-tutorial-part3-linkedlist.png
437
438 \section1 Définition de la classe AddressBook
439
440 Pour ajouter les fonctions de navigation au carnet d'adresses, nous avons
441 besoin de deux slots supplémentaires dans notre classe \c AddressBook:
442 \c next() et \c previous(). Ceux-ci sont ajoutés au fichier addressbook.h:
443
444 \snippet tutorials/addressbook/part3/addressbook.h navigation functions
445
446 Nous avons aussi besoin de deux nouveaux objets QPushButton, nous ajoutons
447 donc les variables privées \c nextButton et \c previousButton.
448
449 \snippet tutorials/addressbook/part3/addressbook.h navigation pushbuttons
450
451 \section1 Implémentation de la classe AddressBook
452
453 A l'intérieur du constructeur de \c AddressBook, dans \c addressbook.cpp, nous
454 instancions \c nextButton et \c previousButton et nous les désactivons
455 par défaut. Nous faisons ceci car la navigation ne doit être activée
456 que lorsqu'il y a plus d'un contact dans le carnet d'adresses.
457
458 \snippet tutorials/addressbook/part3/addressbook.cpp navigation pushbuttons
459
460 Nous connectons alors ces boutons à leur slots respectifs:
461
462 \snippet tutorials/addressbook/part3/addressbook.cpp connecting navigation signals
463
464 L'image ci-dessous montre l'interface utilisateur que nous allons créer.
465 Remarquez que cela ressemble de plus en plus à l'interface du programme
466 complet.
467
468 \image addressbook-tutorial-part3-screenshot.png
469
470 Nous suivons les conventions pour les fonctions \c next() et \c previous()
471 en plaçant \c nextButton à droite et \c previousButton à gauche. Pour
472 faire cette mise en page intuitive, nous utilisons un QHBoxLayout pour
473 placer les widgets côte à côte:
474
475 \snippet tutorials/addressbook/part3/addressbook.cpp navigation layout
476
477 L'objet QHBoxLayout, \c buttonLayout2, est ensuite ajouté à \c mainLayout.
478
479 \snippet tutorials/addressbook/part3/addressbook.cpp adding navigation layout
480
481 La figure ci-dessous montre les systèmes de coordonnées pour les widgets du
482 \c mainLayout.
483 \image addressbook-tutorial-part3-labeled-layout.png
484
485 Dans notre méthode \c addContact(), nous avons desactivé ces boutons
486 pour être sûr que l'utilisateur n'utilise pas la navigation lors de
487 l'ajout d'un contact.
488
489 \snippet tutorials/addressbook/part3/addressbook.cpp disabling navigation
490
491 Dans notre méthode \c submitContact(), nous activons les boutons de
492 navigation, \c nextButton et \c previousButton, en fonction de la
493 taille de \c contacts. Commen mentionné plus tôt, la navigation n'est
494 activée que si il y a plus d'un contact dans le carnet d'adresses.
495 Les lignes suivantes montrent comment faire cela:
496
497 \snippet tutorials/addressbook/part3/addressbook.cpp enabling navigation
498
499 Nous incluons aussi ces lignes de code dans le bouton \c cancel().
500
501 Souvenez vous que nous voulons émuler une liste-liée ciruculaire à
502 l'aide de l'objet QMap, \c contacts. Pour faire cela, nous obtenons un itérateur
503 sur \c contact dans la méthode \c next(), et ensuite:
504
505 \list
506 \o Si l'itérateur n'est pas à la fin de \c contacts, nous l'incrémentons
507 \o Si l'itérateur est à la fin de \c contacts, nous changeons sa position
508 jusqu'au début de \c contacts. Cela donne l'illusion que notre QMap
509 fonctionne comme une liste circulaire.
510 \endlist
511
512 \snippet tutorials/addressbook/part3/addressbook.cpp next() function
513
514 Une fois que nous avons itéré jusqu'à l'objet recherché dans \c contacts,
515 nous affichons son contenu sur \c nameLine et \c addressText.
516
517 De la même façon, pour la méthode \c previous(), nous obtenons un
518 itérateur sur \c contacts et ensuite:
519
520 \list
521 \o Si l'itérateur est à la fin de \c contacts, on réinitialise
522 l'affichage et on retourne.
523 \o Si l'itérateur est au début de \c contacts, on change sa
524 position jusqu'à la fin
525 \o Ensuite, on décrémente l'itérateur
526 \endlist
527
528 \snippet tutorials/addressbook/part3/addressbook.cpp previous() function
529
530 à nouveau, nous affichons le contenu de l'objet courant dans \c contacts.
531
532*/
533
534/*!
535
536 \page tutorials-addressbook-fr-part4.html
537 \previouspage {tutorials/addressbook-fr/part3}{Chapitre 3}
538 \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
539 \nextpage {tutorials/addressbook-fr/part5}{Chapitre 5}
540 \example tutorials/addressbook-fr/part4
541 \title Carnet d'Adresses 4 - éditer et supprimer des adresses
542
543
544 Dans ce chapitre, nous verrons comment modifier les données des contacts
545 contenus dans l'application carnet d'adresses.
546
547
548 \image addressbook-tutorial-screenshot.png
549
550 Nous avons maintenant un carnet d'adresses qui ne se contente pas de
551 lister des contacts de façon ordonnée, mais permet également la
552 navigation. Il serait pratique d'inclure des fonctions telles qu'éditer et
553 supprimer, afin que les détails associés à un contact puissent être
554 modifiés lorsque c'est nécessaire. Cependant, cela requiert une légère
555 modification, sous la forme d'énumérations. Au chapitre précédent, nous avions deux
556 modes: \c {AddingMode} et \c {NavigationMode}, mais ils n'étaient pas
557 définis en tant qu'énumérations. Au lieu de ça, on activait et désactivait les
558 boutons correspondants manuellement, au prix de multiples redondances dans
559 le code.
560
561 Dans ce chapitre, on définit l'énumération \c Mode avec trois valeurs possibles.
562
563 \list
564 \o \c{NavigationMode},
565 \o \c{AddingMode}, et
566 \o \c{EditingMode}.
567 \endlist
568
569 \section1 Définition de la classe AddressBook
570
571 Le fichier \c addressbook.h est mis a jour pour contenir l'énumération \c Mode :
572
573 \snippet tutorials/addressbook/part4/addressbook.h Mode enum
574
575 On ajoute également deux nouveaux slots, \c editContact() et
576 \c removeContact(), à notre liste de slots publics.
577
578 \snippet tutorials/addressbook/part4/addressbook.h edit and remove slots
579
580 Afin de basculer d'un mode à l'autre, on introduit la méthode
581 \c updateInterface() pour contrôller l'activation et la désactivation de
582 tous les objets QPushButton. On ajoute également deux nouveaux boutons,
583 \c editButton et \c removeButton, pour les fonctions d'édition
584 et de suppression mentionnées plus haut.
585
586 \snippet tutorials/addressbook/part4/addressbook.h updateInterface() declaration
587 \dots
588 \snippet tutorials/addressbook/part4/addressbook.h buttons declaration
589 \dots
590 \snippet tutorials/addressbook/part4/addressbook.h mode declaration
591
592 Enfin, on déclare \c currentMode pour garder une trace du mode
593 actuellement utilisé.
594
595 \section1 Implémentation de la classe AddressBook
596
597 Il nous faut maintenant implémenter les fonctionnalités de changement de
598 mode de l'application carnet d'adresses. Les boutons \c editButton et
599 \c removeButton sont instanciés et désactivés par défaut, puisque le
600 carnet d'adresses démarre sans aucun contact en mémoire.
601
602 \snippet tutorials/addressbook/part4/addressbook.cpp edit and remove buttons
603
604 Ces boutons sont ensuite connectés à leurs slots respectifs,
605 \c editContact() et \c removeContact(), avant d'être ajoutés à
606 \c buttonLayout1.
607
608 \snippet tutorials/addressbook/part4/addressbook.cpp connecting edit and remove
609 \dots
610 \snippet tutorials/addressbook/part4/addressbook.cpp adding edit and remove to the layout
611
612 La methode \c editContact() place les anciens détails du contact dans
613 \c oldName et \c oldAddress, avant de basculer vers le mode
614 \c EditingMode. Dans ce mode, les boutons \c submitButton et
615 \c cancelButton sont tous deux activés, l'utilisateur peut par conséquent
616 modifier les détails du contact et cliquer sur l'un de ces deux boutons
617 par la suite.
618
619 \snippet tutorials/addressbook/part4/addressbook.cpp editContact() function
620
621 La méthode \c submitContact() a été divisée en deux avec un bloc
622 \c{if-else}. On teste \c currentMode pour voir si le mode courant est
623 \c AddingMode. Si c'est le cas, on procède à l'ajout.
624
625 \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function beginning
626 \dots
627 \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function part1
628
629 Sinon, on s'assure que \c currentMode est en \c EditingMode. Si c'est le
630 cas, on compare \c oldName et \c name. Si le nom a changé, on supprime
631 l'ancien contact de \c contacts et on insère le contact mis a jour.
632
633 \snippet tutorials/addressbook/part4/addressbook.cpp submitContact() function part2
634
635 Si seule l'adresse a changé (i.e. \c oldAddress n'est pas identique à
636 \c address), on met à jour l'adresse du contact. Enfin on règle
637 \c currentMode à \c NavigationMode. C'est une étape importante puisque
638 c'est cela qui réactive tous les boutons désactivés.
639
640 Afin de retirer un contact du carnet d'adresses, on implémente la méthode
641 \c removeContact(). Cette méthode vérifie que le contact est présent dans
642 \c contacts.
643
644 \snippet tutorials/addressbook/part4/addressbook.cpp removeContact() function
645
646 Si c'est le cas, on affiche une boîte de dialogue QMessageBox, demandant
647 confirmation de la suppression à l'utilisateur. Une fois la confirmation
648 effectuée, on appelle \c previous(), afin de s'assurer que l'interface
649 utilisateur affiche une autre entrée, et on supprime le contact en
650 utilisant le méthode \l{QMap::remove()}{remove()} de \l{QMap}. Dans un
651 souci pratique, on informe l'utilisateur de la suppression par le biais
652 d'une autre QMessageBox. Les deux boîtes de dialogue utilisées dans cette
653 méthode sont représentées ci-dessous.
654
655 \image addressbook-tutorial-part4-remove.png
656
657 \section2 Mise à jour de l'Interface utilisateur
658
659 On a évoqué plus haut la méthode \c updateInterface() comme moyen
660 d'activer et de désactiver les différents boutons de l'interface en
661 fonction du mode. Cette méthode met à jour le mode courant selon
662 l'argument \c mode qui lui est passé, en l'assignant à \c currentMode,
663 avant de tester sa valeur.
664
665 Chacun des boutons est ensuite activé ou désactivé, en fonction du mode.
666 Le code source pour les cas \c AddingMode et \c EditingMode est visible
667 ci-dessous:
668
669 \snippet tutorials/addressbook/part4/addressbook.cpp update interface() part 1
670
671 Dans le cas de \c NavigationMode, en revanche, des tests conditionnels
672 sont passés en paramètre de QPushButton::setEnabled(). Ceci permet de
673 s'assurer que les boutons \c editButton et \c removeButton ne sont activés
674 que s'il existe au moins un contact dans le carnet d'adresses;
675 \c nextButton et \c previousButton ne sont activés que lorsqu'il existe
676 plus d'un contact dans le carnet d'adresses.
677
678 \snippet tutorials/addressbook/part4/addressbook.cpp update interface() part 2
679
680 En effectuant les opérations de réglage du mode et de mise à jour de
681 l'interface utilisateur au sein de la même méthode, on est à l'abri de
682 l'éventualité où l'interface utilisateur se "désynchronise" de l'état
683 interne de l'application.
684
685*/
686
687/*!
688 \page tutorials-addressbook-fr-part5.html
689 \previouspage {tutorials/addressbook-fr/part4}{Chapitre 4}
690 \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
691 \nextpage {tutorials/addressbook-fr/part6}{Chapitre 6}
692 \example tutorials/addressbook-fr/part5
693 \title Carnet d'adresse 5 - Ajout d'une fonction de recherche
694
695 Dans ce chapitre, nous allons voir les possibilités pour rechercher
696 des contacts dans le carnet d'adresse.
697
698 \image addressbook-tutorial-part5-screenshot.png
699
700 Plus nous ajoutons des contacts dans l'application, plus
701 il devient difficile de naviguer avec les boutons \e Next et \e Previous.
702 Dans ce cas, une fonction de recherche serait plus efficace pour rechercher
703 les contacts.
704 La capture d'écran ci-dessus montre le bouton de recherche \e Find et sa position
705 dans le paneau de bouton.
706
707 Lorsque l'utilisateur clique sur le bouton \e Find, il est courant d'afficher
708 une boîte de dialogue qui demande à l'utilisateur d'entrer un nom de contact.
709 Qt fournit la classe QDialog, que nous sous-classons dans ce chapitre pour
710 implémenter la class \c FindDialog.
711
712 \section1 Définition de la classe FindDialog
713
714 \image addressbook-tutorial-part5-finddialog.png
715
716 Pour sous-classer QDialog, nous commençons par inclure le header de
717 QDialog dans le fichier \c finddialog.h. De plus, nous déclarons les
718 classes QLineEdit et QPushButton car nous utilisons ces widgets dans
719 notre classe dialogue.
720
721 Tout comme dans la classe \c AddressBook, la classe \c FindDialog utilise
722 la macro Q_OBJECT et son constructeur est défini de façon à accepter
723 un QWidget parent, même si cette boîte de dialogue sera affichée dans une
724 fenêtre séparée.
725
726 \snippet tutorials/addressbook/part5/finddialog.h FindDialog header
727
728 Nous définissons la méthode publique \c getFindText() pour être utilisée
729 par les classes qui instancient \c FindDialog, ce qui leur permet d'obtenir
730 le texte entré par l'utilisateur. Un slot public, \c findClicked(), est
731 défini pour prendre en charge le texte lorsque l'utilisateur clique sur
732 le bouton \gui Find.
733
734 Finalement, nous définissons les variables privées \c findButton,
735 \c lineEdit et \c findText, qui correspondent respectivement au bouton
736 \gui Find, au champ de texte dans lequel l'utilisateur tape le texte
737 à rechercher, et à une variable interne stockant le texte pour une
738 utilisation ultérieure.
739
740 \section1 Implémentation de la classe FindDialog
741
742 Dans le constructeur de \c FindDialog, nous instancions les objets des
743 variables privées \c lineEdit, \c findButton et \c findText. Nous utilisons ensuite
744 un QHBoxLayout pour positionner les widgets.
745
746 \snippet tutorials/addressbook/part5/finddialog.cpp constructor
747
748 Nous mettons en place la mise en page et le titre de la fenêtre, et
749 nous connectons les signaux aux slots. Remarquez que le signal
750 \l{QPushButton::clicked()}{clicked()} de \c{findButton} est connecté
751 à \c findClicked() et \l{QDialog::accept()}{accept()}. Le slot
752 \l{QDialog::accept()}{accept()} fourni par le QDialog ferme
753 la boîte de dialogue et lui donne le code de retour \l{QDialog::}{Accepted}.
754 Nous utilisons cette fonction pour aider la méthode \c findContact() de la classe
755 \c{AddressBook} à savoir si l'objet \c FindDialog a été fermé. Ceci sera
756 expliqué plus loin lorsque nous verrons la méthode \c findContact().
757
758 \image addressbook-tutorial-part5-signals-and-slots.png
759
760 Dans \c findClicked(), nous validons le champ de texte pour nous
761 assurer que l'utilisateur n'a pas cliqué sur le bouton \gui Find sans
762 avoir entré un nom de contact. Ensuite, nous stockons le texte du champ
763 d'entrée \c lineEdit dans \c findText. Et finalement nous vidons le
764 contenu de \c lineEdit et cachons la boîte de dialogue.
765
766 \snippet tutorials/addressbook/part5/finddialog.cpp findClicked() function
767
768 La variable \c findText a un accesseur publique associé: \c getFindText().
769 Étant donné que nous ne modifions \c findText directement que dans le
770 constructeur et la méthode \c findClicked(), nous ne créons pas
771 de manipulateurs associé à \c getFindText().
772 Puisque \c getFindText() est publique, les classes instanciant et
773 utilisant \c FindDialog peuvent toujours accéder à la chaîne de
774 caractères que l'utilisateur a entré et accepté.
775
776 \snippet tutorials/addressbook/part5/finddialog.cpp getFindText() function
777
778 \section1 Définition de la classe AddressBook
779
780 Pour utiliser \c FindDialog depuis la classe \c AddressBook, nous
781 incluons \c finddialog.h dans le fichier \c addressbook.h.
782
783 \snippet tutorials/addressbook/part5/addressbook.h include finddialog's header
784
785 Jusqu'ici, toutes les fonctionnalités du carnet d'adresses ont un
786 QPushButton et un slot correspondant. De la même façon, pour la
787 fonctionnalité \gui Find, nous avons \c findButton et \c findContact().
788
789 Le \c findButton est déclaré comme une variable privée et la
790 méthode \c findContact() est déclarée comme un slot public.
791
792 \snippet tutorials/addressbook/part5/addressbook.h findContact() declaration
793 \dots
794 \snippet tutorials/addressbook/part5/addressbook.h findButton declaration
795
796 Finalement, nous déclarons la variable privée \c dialog que nous allons
797 utiliser pour accéder à une instance de \c FindDialog.
798
799 \snippet tutorials/addressbook/part5/addressbook.h FindDialog declaration
800
801 Une fois que nous avons instancié la boîte de dialogue, nous voulons l'utiliser
802 plus qu'une fois. Utiliser une variable privée nous permet d'y référer
803 à plus d'un endroit dans la classe.
804
805 \section1 Implémentation de la classe AddressBook
806
807 Dans le constructeur de \c AddressBook, nous instancions nos objets privés,
808 \c findbutton et \c findDialog:
809
810 \snippet tutorials/addressbook/part5/addressbook.cpp instantiating findButton
811 \dots
812 \snippet tutorials/addressbook/part5/addressbook.cpp instantiating FindDialog
813
814 Ensuite, nous connectons le signal \l{QPushButton::clicked()}{clicked()} de
815 \c{findButton} à \c findContact().
816
817 \snippet tutorials/addressbook/part5/addressbook.cpp signals and slots for find
818
819 Maintenant, tout ce qui manque est le code de notre méthode \c findContact():
820
821 \snippet tutorials/addressbook/part5/addressbook.cpp findContact() function
822
823 Nous commençons par afficher l'instance de \c FindDialog, \c dialog.
824 L'utilisateur peut alors entrer le nom du contact à rechercher. Lorsque
825 l'utilisateur clique sur le bouton \c findButton, la boîte de dialogue est
826 masquée et le code de retour devient QDialog::Accepted. Ce code de retour
827 vient remplir la condition du premier if.
828
829 Ensuite, nous extrayons le texte que nous utiliserons pour la recherche,
830 il s'agit ici de \c contactName obtenu à l'aide de la méthode \c getFindText()
831 de \c FindDialog. Si le contact existe dans le carnet d'adresse, nous
832 l'affichons directement. Sinon, nous affichons le QMessageBox suivant pour
833 indiquer que la recherche à échouée.
834
835 \image addressbook-tutorial-part5-notfound.png
836*/
837
838/*!
839 \page tutorials-addressbook-part6.html
840 \previouspage {tutorials/addressbook-fr/part5}{Chapitre 5}
841 \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
842 \nextpage {tutorials/addressbook-fr/part7}{Chapitre 7}
843 \example tutorials/addressbook-fr/part6
844 \title Carnet d'Adresses 6 - Sauvegarde et chargement
845
846 Ce chapitre couvre les fonctionnalités de gestion des fichiers de Qt que
847 l'on utilise pour écrire les procédures de sauvegarde et chargement pour
848 l'application carnet d'adresses.
849
850 \image addressbook-tutorial-part6-screenshot.png
851
852 Bien que la navigation et la recherche de contacts soient des
853 fonctionnalités importantes, notre carnet d'adresses ne sera pleinement
854 utilisable qu'une fois que l'on pourra sauvegarder les contacts existants
855 et les charger à nouveau par la suite.
856 Qt fournit de nombreuses classes pour gérer les \l{Input/Output and
857 Networking}{entrées et sorties}, mais nous avons choisi de nous contenter d'une
858 combinaison de deux classes simples à utiliser ensemble: QFile et QDataStream.
859
860 Un objet QFile représente un fichier sur le disque qui peut être lu, et
861 dans lequel on peut écrire. QFile est une classe fille de la classe plus
862 générique QIODevice, qui peut représenter différents types de
863 périphériques.
864
865 Un objet QDataStream est utilisé pour sérialiser des données binaires
866 dans le but de les passer à un QIODevice pour les récupérer dans le
867 futur. Pour lire ou écrire dans un QIODevice, il suffit d'ouvrir le
868 flux, avec le périphérique approprié en paramètre, et d'y lire ou
869 écrire.
870
871 \section1 Définition de la classe AddressBook
872
873 On déclare deux slots publics, \c saveToFile() et \c loadFromFile(),
874 ainsi que deux objets QPushButton, \c loadButton et \c saveButton.
875
876 \snippet tutorials/addressbook/part6/addressbook.h save and load functions declaration
877 \dots
878 \snippet tutorials/addressbook/part6/addressbook.h save and load buttons declaration
879
880 \section1 Implémentation de la classe AddressBook
881
882 Dans notre constructeur, on instancie \c loadButton et \c saveButton.
883 Idéalement, l'interface serait plus conviviale avec des boutons
884 affichant "Load contacts from a file" et "Save contacts to a file". Mais
885 compte tenu de la dimension des autres boutons, on initialise les labels
886 des boutons à \gui{Load...} et \gui{Save...}. Heureusement, Qt offre une
887 façon simple d'ajouter des info-bulles avec
888 \l{QWidget::setToolTip()}{setToolTip()}, et nous l'exploitons de la façon
889 suivante pour nos boutons:
890
891 \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 1
892 \dots
893 \snippet tutorials/addressbook/part6/addressbook.cpp tooltip 2
894
895 Bien qu'on ne cite pas le code correspondant ici, nous ajoutons ces deux boutons au
896 layout de droite, \c button1Layout, comme pour les fonctionnalités précédentes, et
897 nous connectons leurs signaux
898 \l{QPushButton::clicked()}{clicked()} à leurs slots respectifs.
899
900 Pour la sauvegarde, on commence par récupérer le nom de fichier
901 \c fileName, en utilisant QFileDialog::getSaveFileName(). C'est une
902 méthode pratique fournie par QFileDialog, qui ouvre une boîte de
903 dialogue modale et permet à l'utilisateur d'entrer un nom de fichier ou
904 de choisir un fichier \c{.abk} existant. Les fichiers \c{.abk}
905 correspondent à l'extension choisie pour la sauvegarde des contacts de
906 notre carnet d'adresses.
907
908 \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part1
909
910 La boîte de dialogue affichée est visible sur la capture d'écran ci-
911 dessous.
912
913 \image addressbook-tutorial-part6-save.png
914
915 Si \c fileName n'est pas vide, on crée un objet QFile, \c file, à partir
916 de \c fileName. QFile fonctionne avec QDataStream puisqu'il dérive de
917 QIODevice.
918
919 Ensuite, on essaie d'ouvrir le fichier en écriture, ce qui correspond au
920 mode \l{QIODevice::}{WriteOnly}. Si cela échoue, on en informe
921 l'utilisateur avec une QMessageBox.
922
923 \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part2
924
925 Dans le cas contraire, on instancie un objet QDataStream, \c out, afin
926 d'écrire dans le fichier ouvert. QDataStream nécessite que la même
927 version de flux soit utilisée pour la lecture et l'écriture. On s'assure
928 que c'est le cas en spécifiant explicitement d'utiliser la
929 \l{QDataStream::Qt_4_5}{version introduite avec Qt 4.5} avant de
930 sérialiser les données vers le fichier \c file.
931
932 \snippet tutorials/addressbook/part6/addressbook.cpp saveToFile() function part3
933
934 Pour le chargement, on récupère également \c fileName en utilisant
935 QFileDialog::getOpenFileName(). Cette méthode est l'homologue de
936 QFileDialog::getSaveFileName() et affiche également une boîte de
937 dialogue modale permettant à l'utilisateur d'entrer un nom de fichier ou
938 de selectionner un fichier \c{.abk} existant, afin de le charger dans le
939 carnet d'adresses.
940
941 \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part1
942
943 Sous Windows, par exemple, cette méthode affiche une boîte de dialogue
944 native pour la sélection de fichier, comme illustré sur la capture
945 d'écran suivante:
946
947 \image addressbook-tutorial-part6-load.png
948
949 Si \c fileName n'est pas vide, on utilise une fois de plus un objet
950 QFile, \c file, et on tente de l'ouvrir en lecture, avec le mode
951 \l{QIODevice::}{ReadOnly}. De même que précédemment dans notre
952 implémentation de \c saveToFile(), si cette tentative s'avère
953 infructueuse, on en informe l'utilisateur par le biais d'une
954 QMessageBox.
955
956 \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part2
957
958 Dans le cas contraire, on instancie un objet QDataStream, \c in, en
959 spécifiant la version à utiliser comme précédemment, et on lit les
960 informations sérialisées vers la structure de données \c contacts. Notez
961 qu'on purge \c contacts avant d'y mettre les informations lues afin de
962 simplifier le processus de lecture de fichier. Une façon plus avancée de
963 procéder serait de lire les contacts dans un objet QMap temporaire, et
964 de copier uniquement les contacts n'existant pas encore dans
965 \c contacts.
966
967 \snippet tutorials/addressbook/part6/addressbook.cpp loadFromFile() function part3
968
969 Pour afficher les contacts lus depuis le fichier, on doit d'abord
970 valider les données obtenues afin de s'assurer que le fichier lu
971 contient effectivement des entrées de carnet d'adresses. Si c'est le
972 cas, on affiche le premier contact; sinon on informe l'utilisateur du
973 problème par une QMessageBox. Enfin, on met à jour l'interface afin
974 d'activer et de désactiver les boutons de façon appropriée.
975*/
976
977/*!
978 \page tutorials-addressbook-fr-part7.html
979 \previouspage {tutorials/addressbook-fr/part6}{Chapitre 6}
980 \contentspage {Tutoriel "Carnet d'adresses"}{Sommaire}
981 \example tutorials/addressbook-fr/part7
982 \title Carnet d'adresse 7 - Fonctionnalités avancées
983
984 Ce chapitre couvre quelques fonctionnalités additionnelles qui
985 feront de notre carnet d'adresses une application plus pratique
986 pour une utilisation quotidienne.
987
988 \image addressbook-tutorial-part7-screenshot.png
989
990 Bien que notre application carnet d'adresses soit utile en tant que telle,
991 il serait pratique de pouvoir échanger les contacts avec d'autres applications.
992 Le format vCard est un un format de fichier populaire pour échanger
993 ce type de données.
994 Dans ce chapitre, nous étendrons notre carnet d'adresses pour permettre
995 d'exporter des contacts dans des fichiers vCard \c{.vcf}.
996
997 \section1 Définition de la classe AddressBook
998
999 Nous ajoutons un objet QPushButton, \c exportButton, et un slot
1000 public correspondant, \c exportAsVCard(), à notre classe \c AddressBook
1001 dans le fichier \c addressbook.h.
1002
1003 \snippet tutorials/addressbook/part7/addressbook.h exportAsVCard() declaration
1004 \dots
1005 \snippet tutorials/addressbook/part7/addressbook.h exportButton declaration
1006
1007 \section1 Implémentation de la classe AddressBook
1008
1009 Dans le constructeur de \c AddressBook, nous connectons le signal
1010 \l{QPushButton::clicked()}{clicked()} de \c{exportButton} au slot
1011 \c exportAsVCard().
1012 Nous ajoutons aussi ce bouton à \c buttonLayout1, le layout responsable
1013 du groupe de boutons sur la droite.
1014
1015 Dans la méthode \c exportAsVCard(), nous commençons par extraire le
1016 nom du contact dans \n name. Nous déclarons \c firstname, \c lastName et
1017 \c nameList.
1018 Ensuite, nous cherchons la position du premier espace blanc de \c name.
1019 Si il y a un espace, nous séparons le nom du contact en \c firstName et
1020 \c lastName. Finalement, nous remplaçons l'espace par un underscore ("_").
1021 Si il n'y a pas d'espace, nous supposons que le contact ne comprend que
1022 le prénom.
1023
1024 \snippet tutorials/addressbook/part7/addressbook.cpp export function part1
1025
1026 Comme pour la méthode \c saveToFile(), nous ouvrons une boîte de dialogue
1027 pour donner la possibilité à l'utilisateur de choisir un emplacement pour
1028 le fichier. Avec le nom de fichier choisi, nous créons une instance de QFile
1029 pour y écrire.
1030
1031 Nous essayons d'ouvrir le fichier en mode \l{QIODevice::}{WriteOnly}. Si
1032 cela échoue, nous affichons un QMessageBox pour informer l'utilisateur
1033 à propos de l'origine du problème et nous quittons la méthode. Sinon, nous passons le
1034 fichier comme paramètre pour créer un objet QTextStream, \c out. De la même façon que
1035 QDataStream, la classe QTextStream fournit les fonctionnalités pour
1036 lire et écrire des fichiers de texte. Grâce à celà, le fichier \c{.vcf}
1037 généré pourra être ouvert et édité à l'aide d'un simple éditeur de texte.
1038
1039 \snippet tutorials/addressbook/part7/addressbook.cpp export function part2
1040
1041 Nous écrivons ensuite un fichier vCard avec la balise \c{BEGIN:VCARD},
1042 suivit par \c{VERSION:2.1}.
1043 Le nom d'un contact est écrit à l'aide de la balise \c{N:}. Pour la balise
1044 \c{FN:}, qui remplit le titre du contact, nous devons vérifier si le contact
1045 à un nom de famille défini ou non. Si oui, nous utilions les détails de
1046 \c nameList pour remplir le champ, dans le cas contraire on écrit uniquement le contenu
1047 de \c firstName.
1048
1049 \snippet tutorials/addressbook/part7/addressbook.cpp export function part3
1050
1051 Nous continuons en écrivant l'adresse du contact. Les points-virgules
1052 dans l'adresse sont échappés à l'aide de "\\", les retours de ligne sont
1053 remplacés par des points-virgules, et les vigules sont remplacées par des espaces.
1054 Finalement nous écrivons les balises \c{ADR;HOME:;} suivies par l'adresse
1055 et la balise \c{END:VCARD}.
1056
1057 \snippet tutorials/addressbook/part7/addressbook.cpp export function part4
1058
1059 À la fin de la méthode, un QMessageBox est affiché pour informer l'utilisateur
1060 que la vCard a été exportée avec succès.
1061
1062 \e{vCard est une marque déposée de \l{http://www.imc.org}
1063 {Internet Mail Consortium}}.
1064*/
Note: See TracBrowser for help on using the repository browser.