addressbook-sdk.qdoc 32.3 KB
Newer Older
1
2
3
/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4
** Contact: Nokia Corporation (qt-info@nokia.com)
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the either Technology Preview License Agreement or the
** Beta Release License Agreement.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3.0 as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU General Public License version 3.0 requirements will be
** met: http://www.gnu.org/copyleft/gpl.html.
**
** If you are unsure which license is appropriate for your use, please
37
** contact the sales department at http://www.qtsoftware.com/contact.
38
39
40
41
42
43
44
45
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
    \page tutorials-addressbook-sdk.html

    \startpage {index.html}{Qt Reference Documentation}
46
    \nextpage {examples/addressbook-sdk/part1}{Chapter 1}
47
48
49
50
51
52
53
54

    \title Address Book Tutorial
    \brief An introduction to GUI programming with Qt and Qt Creator,
    describing in detail how to put together a simple yet fully-
    functioning application.

    This tutorial gives an introduction to GUI programming using the Qt SDK.

55
    \image addressbook-tutorial-screenshot.png
56
57
58
59
60
61
62
63
64
65
66

    In the process, we will learn about some basic technologies provided by
    Qt, such as:

    \list
        \o  Widgets and layout managers
        \o  Container classes
        \o  Signals and slots
        \o  Input and output devices
    \endlist

67
68
69
    All these technologies will be introduced via the Qt Creator Integrated
    Development Environment (IDE).

70
71
72
73
74
75
76
77
78
    If you are completely new to Qt, please read \l{How to Learn Qt} if you
    have not already done so.

    The tutorial's source code is located in Qt's
    \c{examples/tutorials/addressbook} directory.

    Tutorial chapters:

    \list 1
79
80
81
82
83
84
85
        \o \l{examples/addressbook-sdk/part1}{Designing the User Interface}
        \o \l{examples/addressbook-sdk/part2}{Adding Addresses}
        \o \l{examples/addressbook-sdk/part3}{Navigating between Entries}
        \o \l{examples/addressbook-sdk/part4}{Editing and Removing Addresses}
        \o \l{examples/addressbook-sdk/part5}{Adding a Find Function}
        \o \l{examples/addressbook-sdk/part6}{Loading and Saving}
        \o \l{examples/addressbook-sdk/part7}{Additional Features}
86
87
88
89
90
91
92
93
    \endlist

    Although this little application does not look much like a fully-fledged
    modern GUI application, it uses many of the basic techniques that are used
    in more complex applications. After you have worked through it, we
    recommend checking out the \l{mainwindows/application}{Application}
    example, which presents a small GUI application, with menus, toolbars, a
    status bar, and so on.
94

95
96
97
98
99
100
*/


/*!
    \page tutorials-addressbook-sdk-part1.html
    \contentspage {Address Book Tutorial}{Contents}
Kavindra Devi Palaraja's avatar
Kavindra Devi Palaraja committed
101
    \nextpage {examples/addressbook-sdk/part2}{Chapter 2}
102
    \example examples/addressbook-sdk/part1
103
104
105
106
107
108
109
110
111
112
113
114
115
116
    \title Address Book 1 - Designing the User Interface

    The first part of this tutorial covers the design of the basic graphical
    user interface (GUI) we use for the Address Book application.

    The first step to creating a GUI program is to design the user interface.
    In this chapter, our goal is to set up the labels and input fields needed
    to implement a basic address book application. The figure below is a
    screenshot of our expected output.

    \image addressbook-tutorial-part1-screenshot.png

    We begin by launching Qt Creator and use it to generate a new project. To
    do this, select \gui New from the \gui File menu. In the
117
118
119
120
    \gui{New...} dialog, select \gui{Projects|Qt4 Gui Application}. For a step
    by step guide on how to create a \gui Project with Qt Creator, refer to the
    \l{Creating a Project in Qt Creator}. Ensure that you select QWidget as
    your subclass and name it \c AddressBook.
121

122
    Five files will be generated in this \gui{Project}:
123
124
125
126
127
128
129
130
131
132
133
134

    \list
        \o  \c{addressbook.pro} - the project file,
        \o  \c{addressbook.h} - the definition file for the \c AddressBook
            class,
        \o  \c{addressbook.cpp} - the implementation file for the
            \c AddressBook class,
        \o  \c{main.cpp} - the file containing a \c main() function, with an
            instance of \c AddressBook, and
        \o  \c{addressbook.ui} - the user interface file created with \QD.
    \endlist

135
    Now that we have all the files we need, let's move on to designing the user
136
137
    interface.

138

139
    \section1 Placing Widgets on the Form
140
141
142
143
144

    In the \gui{Project Sidebar}, double-click on the \c{addressbook.ui} file.
    The \QD plugin will be launched, allowing you to design your program's user
    interface.

145
146
147
    We require two \l{QLabel}s to label the input fields as well as a QLineEdit
    and a QTextEdit for the input fields. So, drag those widgets from the
    \gui{Widget Box} to your form. In the \gui{Property Editor}, set their
148
149
150
151
152
153
154
155
    \gui{objectName} property to \c nameLabel and \c addressLabel for the
    \l{QLabel}s, \c nameLine for the QLineEdit and finally, \c addressText for
    the QTextEdit.

    Next, we have to position the widgets properly, according to the screenshot
    earlier. We use a QGridLayout to position our labels and input fields in a
    structured manner. QGridLayout divides the available space into a grid and
    places widgets in the cells we specify with row and column numbers. The
156
157
158
    diagram below shows the layout cells and the position of our widgets. Place
    your widgets accordingly and save the form by choosing
    \gui{File | Save} or using the \key{Ctrl+S} shortcut.
159
160
161

    \image addressbook-tutorial-part1-labeled-screenshot.png

162
163
164
165
166
    A common mistake when designing user interfaces with \QD is overlooking the
    top level widget's layout. Unlike sub-layouts, which \QD displays with a
    red border, top level layouts have no graphical representation. Layouts are
    necessary for top level widgets, in this case QWidget, to ensure that when
    the window is resized, the widgets on the form will resize accordingly. You
167
    can try this out by pressing \key{Ctrl+Alt+R} now. To correct it, simply click
168
169
170
    anywhere on the form and select \gui{Lay out Horizontally} or
    \gui{Lay out Vertically}. The output will be the same. Now your widgets
    will resize correctly.
171

172

173
    \section1 The AddressBook Class
174
175
176
177

    The \l{examples/addressbook-sdk/part1/addressbook.h}{\c addressbook.h} file
    is used to define the \c AddressBook class.

178
    Let's take a look at what is already provided for us by Qt Creator. The
179
    \c AddressBook class has been defined as a QWidget subclass with a
180
    constructor and destructor.The Q_OBJECT macro is used to indicate that this
181
182
183
    class uses internationalization as well as Qt's signals and slots features.
    Although the macro implements some of Qt's more advanced features, for now,
    it is useful to think of it as a shortcut that allows us to use the
184
    \l{QObject::}{tr()} and \l{QObject::}{connect()} functions.
185
186
187

    \snippet examples/addressbook-sdk/part1/addressbook.h class definition

188
189
    Qt Creator's \gui{Project Wizard} provides us with the \c Ui object as a
    way to access the widgets on our form.
190

191
192
193
    The \l{examples/addressbook-sdk/part1/addressbook.cpp}{\c addressbook.cpp}
    file is used to implement the \c AddressBook class. The constructor sets up
    the \c ui file; the destructor deletes it.
194

195
    \snippet examples/addressbook-sdk/part1/addressbook.cpp class implementation
196

197

198
    \section1 The \c{main()} Function
199

200
201
202
203
204
    The \l{examples/addressbook-sdk/part1/main.cpp}{\c main.cpp} file contains
    the \c{main()} function  It is generated by the \gui{Project Wizard}.
    Within this function, a QApplication object, \c a, is instantiated.
    QApplication is responsible for various application-wide resources, such as
    the default font and cursor, and for running an event loop. Hence, there is
205
    always one QApplication object in every GUI application using Qt.
206

207
    \snippet examples/addressbook-sdk/part1/main.cpp main function
208

209
210
211
    The code constructs a new \c AddressBook widget on the stack and 
    invokes its \l{QWidget::}{show()} function to display it. 
    However, the widget will not be shown until the application's event
212
213
214
215
216
217
218
219
220
221
222
    loop is started. This is done by calling the application's
    \l{QApplication::}{exec()} function. Finally, the result returned by
    \l{QApplication::}{exec()} is used as the \c main() function's return
    value.


    \section1 Running the Application

    To run your application with Qt Creator, simply click on the Play button
    (image). A bare bones Address Book will be displayed. Click on the X button
    to close it.
223

224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247

    \section1 Qt Programming - Subclassing

    When writing Qt programs, we usually subclass Qt objects to add
    functionality. This is one of the essential concepts behind creating custom
    widgets or collections of standard widgets. Subclassing to extend or change
    the behavior of a widget has the following advantages:

    \list
        \o  We can write implementations of virtual or pure virtual functions
            to obtain exactly what we need, falling back on the base class's
            implementation when necessary.
        \o  It allows us to encapsulate parts of the user interface within a
            class, so that the other parts of the application do not need to
            know about the individual widgets in the user interface.
        \o  The subclass can be used to create multiple custom widgets in the
            same application or library, and the code for the subclass can be
            reused in other projects.
    \endlist

    Since Qt does not provided a specific address book widget, we subclass a
    standard Qt widget class and add features to it. The \c AddressBook class
    we create in this tutorial can be reused in situations where a basic
    address book is needed.
248
*/
249

250

251
252
253
254
/*!
    \page tutorials-addressbook-sdk-part2.html
    \previouspage Address Book 1 - Designing the User Interface
    \contentspage {Address Book Tutorial}{Contents}
Kavindra Devi Palaraja's avatar
Kavindra Devi Palaraja committed
255
    \nextpage {examples/addressbook-sdk/part3}{Chapter 3}
256
257
258
259
260
261
    \example examples/addressbook-sdk/part2
    \title Address Book 2 - Adding Addresses

    The next step to creating our basic address book application is to allow a
    little bit of user interaction.

Kavindra Palaraja's avatar
Kavindra Palaraja committed
262
    \image addressbook-tutorial-part2-add-contact.png
263
264
265
266
267
268
269
270

    We will provide a push button that the user can click to add a new contact.
    Also, some form of data structure is needed to store these contacts in an
    organized way.


    \section1 Placing Widgets on the Form

271
272
273
    We shall continue with the form we had from the last chapter; we have the
    labels and input fields set up, but we need to add push buttons to complete
    the process of adding a contact. So, we begin by breaking the existing
274
275
276
277
278
    layouts: select \gui{Break Layout} from the context menu. You might have to
    do a \gui{Select All} with \key{Ctrl+A} first.. Then, we add three push
    buttons. Double-click on each of them to set their text to "Add", "Submit",
    and "Cancel". We now require a vertical spacer to ensure that the push
    buttons will be laid out neatly; drag one from the \gui{Widget Box}.
279
280
281
282
283
284
285
286
287

    Next, lay out these three push buttons and the spacer vertically, by
    selecting all three of them (using the \key{Ctrl + click}) and choosing
    \gui{Lay out Vertically} from the context menu. Alternatively you can click
    on the ... button or use the \key{Ctrl+L} shortcut. We use the spacer as we
    do not want the buttons to be evenly spaced, but arranged closer to the top
    of the widget. The figure below shows the difference between using the
    spacer and not using it.

Kavindra Palaraja's avatar
Kavindra Palaraja committed
288
    \image addressbook-tutorial-part2-stretch-effects.png
289
290

    Select all the objects on the form (use \key{Ctrl+A}) and lay them out in a
291
292
293
    grid. Lastly, set the top level widget's layout by right-clicking anywhere
    on the widget and selecting \gui{Lay out Horizontally} or
    \gui{Lay out Vertically}.
294

295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
    The final design of the form is shown in the screenshot below:

    ## image


    \section1 The AddressBook Class

    To ensure that the Address Book reacts to user interaction, we need to
    write slots for each push button that we added earlier. A slot is a
    function that responds to a particular signal. We will discuss this
    concept in further detail below. However, for an overview of Qt's signals
    and slots concept, you can refer to the \l{Signals and Slots} document.

    In the \l{examples/addressbook-sdk/part2/addressbook.h}{\c addressbook.h}
    file, we add the following code:

    \snippet examples/addressbook-sdk/part2/addressbook.h slot definition

    Next, we have to provide private members for the \c AddressBook class so
314
    that we can access these widgets freely throughout the class.
315

316
317
    \snippet examples/addressbook-sdk/part2/addressbook.h members1

318
319
320
    \note The names, e.g., \c addButton etc., correspond to the name of the
    actual object. You can modify them by double-clicking on their names within
    \QD's \gui{Object Inspector}.
321

322
323
324
325
    We need a container to store our address book contacts, so that we can
    traverse and display them. A QMap object, \c contacts, is used for this
    purpose as it holds a key-value pair: the contact's name as the \e key, and
    the contact's address as the \e value.
326

327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
    \snippet examples/addressbook-sdk/part2/addressbook.h members2

    We also declare two private QString objects, \c oldName and \c oldAddress.
    These objects are needed to hold the name and address of hte contact that
    was last displayed, before the user clicked \gui Add. So, when the user
    clicks \gui Cancel, we can revert to displaying the details of the last
    contact.

    Let's move on to implementing the slots we defined earlier. Within the
    constructor of \c AddressBook, we extract the widgets from the form using
    the \c ui object by pointing our private members to them.

    \snippet examples/addressbook-sdk/part2/addressbook.cpp extract objects

    Then we set \c nameLine and \c addressText to read-only, so that we can
    only display but not edit existing contact details. We also hide
    \c submitButton and \c cancelButton as they will only be be displayed
    when the user clicks \gui Add, and this is handled by the \c addContact()
    function discussed below.

    \snippet examples/addressbook-sdk/part2/addressbook.cpp signal slot

349
350
    We connect the push buttons' \l{QAbstractButton::}{clicked()} signal to
    their respective slots. The figure below illustrates this.
351

Kavindra Palaraja's avatar
Kavindra Palaraja committed
352
    \image addressbook-tutorial-part2-signals-and-slots.png
353

354
355
356
357
358
    Finally, we set the window title to "Simple Address Book" using the
    \l{QWidget::}{setWindowTitle()} function.

    \snippet examples/addressbook-sdk/part2/addressbook.cpp window title

359
360
    \section2 The \c{addContact()} Function

361
362
363
364
    In this function, we begin by storing the last displayed contact details
    in \c oldName and \c oldAddress. Then we clear these input fields and turn
    off the read-only mode. The focus is set on \c nameLine and we display
    \c submitButton and \c cancelButton; but we disable \c addButton.
365

366
    \snippet examples/addressbook-sdk/part2/addressbook.cpp addContact
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398

    \section2 The \c{submitContact()} Function

    This function can be divided into three parts:

    \list 1
        \o  We extract the contact's detail from \c nameLine and \c addressText
            and store them in QString objects. We also validate to ensure that
            the user did not click \gui Submit with empty input fields;
            otherwise, a QMessageBox is displayed to remind the user for a name
            and address.

            \snippet examples/addressbook-sdk/part2/addressbook.cpp submitContact part1

        \o  We then proceed to check if the contact already exists. If it does
            not exist, we add the contact to \c contacts and we display a
            QMessageBox to inform the user about this, preventing the user from
            adding duplicate contacts. Our \c contacts object is based on
            key-value pairs or name and address, hence, we want to ensure that
            \e key is unique.

            \snippet examples/addressbook-sdk/part2/addressbook.cpp submitContact part2

        \o  Once we have handled both cases mentioned above, we restore the
            push buttons to their normal state with the following code:

            \snippet examples/addressbook-sdk/part2/addressbook.cpp submitContact part3
    \endlist

    The screenshot below shows the QMessageBox object we use to display
    information messages to the user.

Kavindra Palaraja's avatar
Kavindra Palaraja committed
399
    \image addressbook-tutorial-part2-add-successful.png
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419

    \section2 The \c{cancel()} Function

    This function restores the last displayed contact details and enables
    \c addButton, as well as hides \c submitButton and \c cancelButton.

    \snippet examples/addressbook-sdk/part2/addressbook.cpp cancel

    The general idea behind adding a contact is to give the user the
    flexibility to click \gui Submit or \gui Cancel at any time. The flowchart
    below further explains this concept:

    \image addressbook-tutorial-part2-add-flowchart.png


    \section1 Running the Application

    Run your application now. You will be able to add as many unique contacts
    as you like.

420
*/
421
422
423
424
425
426


/*!
    \page tutorials-addressbook-sdk-part3.html
    \previouspage Address Book 2 - Adding Addresses
    \contentspage {Address Book Tutorial}{Contents}
Kavindra Devi Palaraja's avatar
Kavindra Devi Palaraja committed
427
    \nextpage {examples/addressbook-sdk/part4}{Chapter 4}
428
    \example examples/addressbook-sdk/part3
Kavindra Devi Palaraja's avatar
Kavindra Devi Palaraja committed
429
    \title Address Book 3 - Navigating between Entries
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449

    The address book application is now half complete. We need to add some
    functions to navigate between contacts. But first, we have to decide what
    sort of a data structure we would like to use to hold these contacts.

    In Chapter 2, we used a QMap of key-value pairs with the contact's name as
    the \e key, and the contact's address as the \e value. This works well for
    our case. However, in order to navigate and display each entry, a little
    bit of enhancement is needed.

    We enhance the QMap by making it replicate a data structure similar to a
    circularly-linked list, where all elements are connected, including the
    first element and the last element. The figure below illustrates this data
    structure;

    \image addressbook-tutorial-part3-linkedlist.png


    \section1 Placing Widgets on the Form

450
451
452
    So far, our application allows us to add new contacts. However, we also
    need to traverse the existing contacts. To do so, we add two push buttons
    at the bottom of our application and name them: \gui Next and
453
454
455
456
457
458
459
460
461
    \gui Previous. The buttons' \c objectName should be \c nextButton and
    \c previousButton, respectively. Then, we break our top level layout.
    Simply right-click on \c AddressBook in the \gui{Object Inspector} and
    then select \gui{Lay out|Break Layout}. Place the \gui Next and
    \gui Previous buttons in a horizontal layout. Now drag and drop the buttons
    together with their layout into the existing grid layout. The screenshot
    below illustrates what you will see as the button layout approaches the
    grid layout; drop it then.

462
    \image addressbook-tutorial-part3-drop-in-gridlayout
463
464

    Finally, set a top level layout for the widget again.
465

466
467
468
469
    \note We follow basic conventions for \c next() and \c previous() functions
    by placing the \c nextButton on the right and the \c previousButton on the
    left.

470

471
472
    \section1 The AddressBook Class

473
474
475
476
477
478
479
480
481
482
    Let's move on to the code. In order to add navigation functions to the
    address book application, we need to add two more slots to our
    \c AddressBook class: \c next() and \c previous().

    \snippet examples/addressbook-sdk/part3/addressbook.h slot definition

    We also define two more QPushButton objects:

    \snippet examples/addressbook-sdk/part3/addressbook.h members

483
484
485
    In the \c AddressBook constructor, we extract the push buttons from the
    \c ui object and disable them by default. This is because navigation is
    only enabled when there is more than one contact in the address book.
486
487
488

    \snippet examples/addressbook-sdk/part3/addressbook.cpp extract objects

489
    Next, we connect the buttons to their respective slots:
490
491
492

    \snippet examples/addressbook-sdk/part3/addressbook.cpp signal slot

493
494
495
    The screenshot below is our expected graphical user interface. Notice that
    it is getting closer to our final application.

Kavindra Palaraja's avatar
Kavindra Palaraja committed
496
497
    \image addressbook-tutorial-part3-screenshot.png

498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
    Within our \c addContact() function, we have to disable the \gui Next and
    \gui Previous buttons so that the user does not attempt to navigate while
    adding a contact.

    \snippet examples/addressbook-sdk/part3/addressbook.cpp disable navigation

    Also, in our \c submitContact() function, we enable the navigation buttons,
    depending on the size of \c contacts. Asmentioned earlier, navigation is
    only enabled when there is more than one contact in the address book. The
    following lines of code demonstrates how to do this:

    \snippet examples/addressbook-sdk/part3/addressbook.cpp enable navigation

    We also include these lins of code in the \c cancel() function.

    Recall that we intend to emulate a circularly-linked list with our QMap
    object, \c contacts. So in the \c next() function, we obtain an iterator
    for \c contacts and then:

    \list
        \o If the iterator is not at the end of \c contacts, we increment it by
           one.
        \o If the iterator is at the end of \c contacts, we move it to the
           beginning of \c contacts. This gives us the illusion that our QMap
           is working like a circularly-linked list.
    \endlist

    \snippet examples/addressbook-sdk/part3/addressbook.cpp next

    Once we have iterated to the current object in \c contacts, we display its
    contents on \c nameLine and \c addressText.

    Similarly, for the \c previous() function,we obtain an iterator for
    \c contacts and then:

    \list
534
        \o  If the iterator is at the end of \c contacts, we clear the display
535
536
537
538
539
            and return.
        \o  If the iterator is at the beginning of \c contacts, we move it to
            the end.
        \o  We then decrement the iterator by one.
    \endlist
540

541
    \snippet examples/addressbook-sdk/part3/addressbook.cpp previous
542

543
    Again, we display the contents of the current object in \c contacts.
544

545
*/
546

547

548
549
550
551
/*!
    \page tutorials-addressbook-sdk-part4.html
    \previouspage Address Book 3 - Navigating between Entries
    \contentspage {Address Book Tutorial}{Contents}
Kavindra Devi Palaraja's avatar
Kavindra Devi Palaraja committed
552
    \nextpage {examples/addressbook-sdk/part5}{Chapter 5}
553
    \example examples/addressbook-sdk/part4
Kavindra Devi Palaraja's avatar
Kavindra Devi Palaraja committed
554
    \title Address Book 4 - Editing and Removing Addresses
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579

    In this chapter, we look at ways to modify the contents of contacts stored
    in the address book application.

    #screenshot

    We now have an address book that not only holds contacts in an organized
    manner, but also allows navigation. It would be convenient to include edit
    and remove functions so that a contact's details can be changed when
    needed. However, this requires a little improvement, in the form of enums.

    In our previous chapters, we had two modes: \c AddingMode and
    \c NavigationMode - but they were not defined as enums. Instead, we enabled
    and disabled the corresponding buttons manually, resulting in multiple
    lines of repeated code.

    In this chapter, we define the \c Mode enum with three different values:
    \list
        \o \c{NavigationMode},
        \o \c{AddingMode}, and
        \o \c{EditingMode}.
    \endlist

    \section1 Placing Widgets on the Form

580
581
582
583
584
585
586
587
588
    To edit and remove contacts, we need two push buttons. Drag them and name
    them accordingly. Their \c objectName properties should be \c editButton
    and \c removeButton, respectively. The quickest way to place these two
    buttons into our existing layout, is to simply drag and drop them. Use the
    screenshot below as a guide:

    \image addressbook-tutorial-part4-drop-in-gridlayout.png


589
590
591
592
593
594
595
596
597
598
599
    \section1 The AddressBook Class

    We update the header file to contain the \c Mode enum:

    \snippet examples/addressbook-sdk/part4/addressbook.h enum

    We also add two new slots, \c editContact() and \c removeContact(), to our
    current list of public slots.

    \snippet examples/addressbook-sdk/part4/addressbook.h slot definition

600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
    In order to switch between modes, we introduce the \c updateInterface()
    function to control the enabling and disabling of all push buttons. We also
    add two new push buttons, \c editButton and \c removeButton, for the edit
    and remove functions mentioned earlier.

    \snippet examples/addressbook-sdk/part4/adressbook.h updateInterface
    \dots
    \snippet examples/addressbook-sdk/part4/addressbook.h members

    Lastly, we declare \c currentMode to keep track of the enum's current mode.

    \snippet examples/addressbook-sdk/part4/addressbook.h current mode

    Let's begin by implementing the mode-changing features of the address book
    application. The \c editButton and \c removeButton are extracted and
    disabled by default, as the address book starts up with zero contacts in
    memory.

618
    \snippet examples/addressbook-sdk/part4/addressbook.cpp extract objects
619

620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
    These buttons are then connected to their respective slots,
    \c editContact() and \c removeContact.

    \snippet examples/addressbook-sdk/part4/addressbook.cpp signal slot

    Now we look at the \c editContact() and \c removeContact() functions in
    detail.


    \section2 The \c{editContact()} Function

    This function stores the contact's old details in \c oldName and
    \c oldAddress, before switching the mode to \c EditingMode. In this mode,
    the \c submitButton and \c cancelButton are both enabled. Hence, the user
    can change the contact's details and click either button.

    \snippet examples/addressbook-sdk/part4/addressbook.cpp editContact

    Since we will reuse the \c submitButton for both: adding a new contact and
    editing an existing contact, we need to modify our existing
    \c submitContact() function. So, we divide it in two with an \c{if-else}
    statement.

    First, we check \c currentMode to see if it is in \c AddingMode. If it is,
    we proceed with our adding process.

    \snippet examples/addressbook-sdk/part4/addressbook.cpp submitContact part1
    \dots
    \snippet examples/addressbook-sdk/part4/addressbook.cpp submitContact part2

    Otherwise, we check to see if \c currentMode is in \c EditingMode. If it
    is, we compare \c oldName with \c name. If the name has changed, we remove
    the old contact from \c contacts and insert the newly updated contact.

    \snippet examples/addressbook-sdk/part4/addressbook.cpp submitContact part3

    If only the contact's address changed, i.e., \c oldAddress is not the same
    as \c address, we update the contact's address. Lastly, we set
    \c currentMode to \c NavigationMode. This is an important step as it
    re-enables all the disabled push buttons.

    To remove a contact from the address book, we implement the
    \c removeContact() function.

    \snippet examples/addressbook-sdk/part4/addressbook.cpp removeContact

    This function first checks to see if the contact exists in \c contacts. If
    it does, we display a QMessageBox, to confirm the removal with the user.
    Once the user has confirmed, we call \c previous() to ensure that the
    user interface shows another contact, and we remove the contact using
    \l{QMap}'s \l{QMap::}{remove()} function. As a courtesy, we display a
    QMessageBox to inform the user. Both the message boxes used in this
    function are shown below:

    # image


    \section2 The \c{updateInterface()} Function

    We mentioned this function earlier as a means to enable and disable the
    push buttons, depending on the current mode. The function updates the
    current mode according to the \c mode argument passed to it, assigning it
    to \c currentMode, before checking its value.\

    Each of the push buttons is then enabled or disabled, depending on the
    current mode. The code for \c AddingMode and \c EditingMode is shown below:

    \snippet examples/addressbook-sdk/part4/addressbook.cpp updateInterface part1

    For \c NavigationMode, however, we include conditions within the parameters
    of the QPushButton::setEnabled() function. This is to ensure that
    \c editButton and \c removeButton are enabled when there is at least one
    contact in the address book; \c nextButton and \c previousButton are only
    enabled when there is more than one contact in the address book.

    \snippet examples/addressbook-sdk/part4/addressbook.cpp updateInterface part2

    By performing the task of setting the mode and updating the user interface
    in the same function, we avoid the possibility of the user interface
    getting "out of sync" with the internal state of the application.
700

701
702
703
704
705
706
    To maintain consistency, we need to modify our \c addContact() and
    \c cancel() functions respectively. Below is the code:

    \snippet examples/addressbook-sdk/part4/addressbook.cpp addContact
    \dots
    \snippet examples/addressbook-sdk/part4/addressbook.cpp cancel
707
708
709
710

    \page tutorials-addressbook-sdk-part5.html
    \previouspage Address Book 4 - Editing and Removing Addresses
    \contentspage {Address Book Tutorial}{Contents}
Kavindra Devi Palaraja's avatar
Kavindra Devi Palaraja committed
711
    \nextpage {examples/addressbook-sdk/part6}{Chapter 6}
712
    \example examples/addressbook-sdk/part5
Kavindra Devi Palaraja's avatar
Kavindra Devi Palaraja committed
713
    \title Address Book 5 - Adding a Find Function
714

715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
    In this chapter, we look at ways to locate contacts and addresses in the
    address book application.

    # image

    As we keep adding contacts to our address book, it becomes tedious to
    navigate them with the \gui Next and \gui Previous buttons. In this case,
    a \gui Find function would be more efficient in looking up contacts. The
    screenshot above shows the \gui Find button and its position on the panel
    of buttons.

    When the user clicks on the \gui Find button, it is useful to display a
    dialog that can prompt the user for a contact's name. Qt provides QDialog,
    which we subclass in this chapter, to implement a FindDialog class.

    \section1 Designing FindDialog

    #image

    We begin by adding a new \c{.ui} file to our project. Right click on your
    project and select \gui{Add New...}. In the \gui{New File} dialog, select
Kavindra Devi Palaraja's avatar
Kavindra Devi Palaraja committed
736
    \gui{Qt Designer Form}. In the \gui{Qt Designer Form} dialog, select
737
738
739
740
741
742
743
744
745
    \e{Dialog without buttons}. Name it \c{finddialog.ui} and add it to your
    project. The \QD plugin within Qt Creator will now display your new form.

    To replicate the screenshot above, we need a label, a line edit, and a push
    button. Drag these onto your form. Set their text accordingly and name them
    \c label, \c lineEdit, and \c findButton, respectively. Place these widgets
    in a horizontal layout. Then set a top level layout - either horizontal or
    vertical.

746
747
*/

748

749
/*!
750
751
752
    \page tutorials-addressbook-sdk-part6.html
    \previouspage Address Book 5 - Adding a Find Function
    \contentspage {Address Book Tutorial}{Contents}
Kavindra Devi Palaraja's avatar
Kavindra Devi Palaraja committed
753
    \nextpage {examples/addressbook-sdk/part7}{Chapter 7}
754
    \example examples/addressbook-sdk/part6
Kavindra Devi Palaraja's avatar
Kavindra Devi Palaraja committed
755
    \title Address Book 6 - Loading and Saving
756

757
758
*/

759

760
/*!
761
762
763
764
    \page tutorials-addressbook-sdk-part7.html
    \previouspage Address Book 6 - Loading and Saving
    \contentspage {Address Book Tutorial}{Contents}
    \example examples/addressbook-sdk/part7
Kavindra Devi Palaraja's avatar
Kavindra Devi Palaraja committed
765
    \title Address Book 7 - Additional Features
766
767

*/