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

Last change on this file since 624 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

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