File: tutorials-addressbook-part2.html

package info (click to toggle)
qt4-x11 4%3A4.8.2%2Bdfsg-11
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 701,696 kB
  • sloc: cpp: 2,686,179; ansic: 375,485; python: 25,859; sh: 19,349; xml: 17,091; perl: 14,765; yacc: 5,383; asm: 5,038; makefile: 1,259; lex: 555; ruby: 526; objc: 347; cs: 112; pascal: 112; php: 54; sed: 34
file content (196 lines) | stat: -rw-r--r-- 19,854 bytes parent folder | download
1
2
3
4
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en_US" lang="en_US">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- addressbook.qdoc -->
  <title>Qt 4.8: Part 2 - Adding Addresses</title>
  <link rel="stylesheet" type="text/css" href="style/offline.css" />
</head>
<body>
<div class="header" id="qtdocheader">
  <div class="content"> 
    <a href="index.html" class="qtref"><span>Qt Reference Documentation</span></a>
  </div>
  <div class="breadcrumb toolblock">
    <ul>
      <li class="first"><a href="index.html">Home</a></li>
      <!--  Breadcrumbs go here -->
<li><a href="all-examples.html">Examples</a></li>
<li>Part 2 - Adding Addresses</li>
    </ul>
  </div>
</div>
<div class="content mainContent">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#defining-the-addressbook-class">Defining the AddressBook Class</a></li>
<li class="level1"><a href="#implementing-the-addressbook-class">Implementing the AddressBook Class</a></li>
</ul>
</div>
<h1 class="title">Part 2 - Adding Addresses</h1>
<span class="subtitle"></span>
<!-- $$$tutorials/addressbook/part2-description -->
<div class="descr"> <a name="details"></a>
<p>Files:</p>
<ul>
<li><a href="tutorials-addressbook-part2-addressbook-cpp.html">tutorials/addressbook/part2/addressbook.cpp</a></li>
<li><a href="tutorials-addressbook-part2-addressbook-h.html">tutorials/addressbook/part2/addressbook.h</a></li>
<li><a href="tutorials-addressbook-part2-main-cpp.html">tutorials/addressbook/part2/main.cpp</a></li>
<li><a href="tutorials-addressbook-part2-part2-pro.html">tutorials/addressbook/part2/part2.pro</a></li>
</ul>
<p>The next step in creating the address book is to implement some user interactions.</p>
<p class="centerAlign"><img src="images/addressbook-tutorial-part2-add-contact.png" alt="" /></p><p>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.</p>
<a name="defining-the-addressbook-class"></a>
<h2>Defining the AddressBook Class</h2>
<p>Now that we have the labels and input fields set up, we add push buttons to complete the process of adding a contact. This means that our <tt>addressbook.h</tt> file now has three <a href="qpushbutton.html">QPushButton</a> objects declared and three corresponding public slots.</p>
<pre class="cpp"> <span class="keyword">public</span> <span class="keyword">slots</span>:
     <span class="type">void</span> addContact();
     <span class="type">void</span> submitContact();
     <span class="type">void</span> cancel();</pre>
<p>A slot is a function that responds to a particular signal. We will discuss this concept in further detail when implementing the <tt>AddressBook</tt> class. However, for an overview of Qt's signals and slots concept, you can refer to the <a href="signalsandslots.html#signals-and-slots">Signals and Slots</a> document.</p>
<p>Three <a href="qpushbutton.html">QPushButton</a> objects (<tt>addButton</tt>, <tt>submitButton</tt>, and <tt>cancelButton</tt>) are now included in our private variable declarations, along with <tt>nameLine</tt> and <tt>addressText</tt>.</p>
<pre class="cpp"> <span class="keyword">private</span>:
     <span class="type"><a href="qpushbutton.html">QPushButton</a></span> <span class="operator">*</span>addButton;
     <span class="type"><a href="qpushbutton.html">QPushButton</a></span> <span class="operator">*</span>submitButton;
     <span class="type"><a href="qpushbutton.html">QPushButton</a></span> <span class="operator">*</span>cancelButton;
     <span class="type"><a href="qlineedit.html">QLineEdit</a></span> <span class="operator">*</span>nameLine;
     <span class="type"><a href="qtextedit.html">QTextEdit</a></span> <span class="operator">*</span>addressText;</pre>
<p>We need a container to store our address book contacts, so that we can traverse and display them. A <a href="qmap.html">QMap</a> object, <tt>contacts</tt>, is used for this purpose as it holds a key-value pair: the contact's name as the <i>key</i>, and the contact's address as the <i>value</i>.</p>
<pre class="cpp">     <span class="type"><a href="qmap.html">QMap</a></span><span class="operator">&lt;</span><span class="type"><a href="qstring.html">QString</a></span><span class="operator">,</span> <span class="type"><a href="qstring.html">QString</a></span><span class="operator">&gt;</span> contacts;
     <span class="type"><a href="qstring.html">QString</a></span> oldName;
     <span class="type"><a href="qstring.html">QString</a></span> oldAddress;
 };</pre>
<p>We also declare two private <a href="qstring.html">QString</a> objects, <tt>oldName</tt> and <tt>oldAddress</tt>. These objects are needed to hold the name and address of the contact that was last displayed, before the user clicked <b>Add</b>. So, when the user clicks <b>Cancel</b>, we can revert to displaying the details of the last contact.</p>
<a name="implementing-the-addressbook-class"></a>
<h2>Implementing the AddressBook Class</h2>
<p>Within the constructor of <tt>AddressBook</tt>, we set the <tt>nameLine</tt> and <tt>addressText</tt> to read-only, so that we can only display but not edit existing contact details.</p>
<pre class="qml">     ...
     nameLine<span class="operator">-</span><span class="operator">&gt;</span>setReadOnly(<span class="keyword">true</span>);
     ...
     addressText<span class="operator">-</span><span class="operator">&gt;</span>setReadOnly(<span class="keyword">true</span>);</pre>
<p>Then, we instantiate our push buttons: <tt>addButton</tt>, <tt>submitButton</tt>, and <tt>cancelButton</tt>.</p>
<pre class="cpp">     addButton <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qpushbutton.html">QPushButton</a></span>(tr(<span class="string">&quot;&amp;Add&quot;</span>));
     addButton<span class="operator">-</span><span class="operator">&gt;</span>show();
     submitButton <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qpushbutton.html">QPushButton</a></span>(tr(<span class="string">&quot;&amp;Submit&quot;</span>));
     submitButton<span class="operator">-</span><span class="operator">&gt;</span>hide();
     cancelButton <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qpushbutton.html">QPushButton</a></span>(tr(<span class="string">&quot;&amp;Cancel&quot;</span>));
     cancelButton<span class="operator">-</span><span class="operator">&gt;</span>hide();</pre>
<p>The <tt>addButton</tt> is displayed by invoking the <a href="qwidget.html#show">show()</a> function, while the <tt>submitButton</tt> and <tt>cancelButton</tt> are hidden by invoking <a href="qwidget.html#hide">hide()</a>. These two push buttons will only be displayed when the user clicks <b>Add</b> and this is handled by the <tt>addContact()</tt> function discussed below.</p>
<pre class="cpp">     connect(addButton<span class="operator">,</span> SIGNAL(clicked())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(addContact()));
     connect(submitButton<span class="operator">,</span> SIGNAL(clicked())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(submitContact()));
     connect(cancelButton<span class="operator">,</span> SIGNAL(clicked())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(cancel()));</pre>
<p>We connect the push buttons' <a href="qabstractbutton.html#clicked">clicked()</a> signal to their respective slots. The figure below illustrates this.</p>
<p class="centerAlign"><img src="images/addressbook-tutorial-part2-signals-and-slots.png" alt="" /></p><p>Next, we arrange our push buttons neatly to the right of our address book widget, using a <a href="qvboxlayout.html">QVBoxLayout</a> to line them up vertically.</p>
<pre class="cpp">     <span class="type"><a href="qvboxlayout.html">QVBoxLayout</a></span> <span class="operator">*</span>buttonLayout1 <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qvboxlayout.html">QVBoxLayout</a></span>;
     buttonLayout1<span class="operator">-</span><span class="operator">&gt;</span>addWidget(addButton<span class="operator">,</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>AlignTop);
     buttonLayout1<span class="operator">-</span><span class="operator">&gt;</span>addWidget(submitButton);
     buttonLayout1<span class="operator">-</span><span class="operator">&gt;</span>addWidget(cancelButton);
     buttonLayout1<span class="operator">-</span><span class="operator">&gt;</span>addStretch();</pre>
<p>The <a href="qboxlayout.html#addStretch">addStretch()</a> function is used to ensure the push buttons are not evenly spaced, but arranged closer to the top of the widget. The figure below shows the difference between using <a href="qboxlayout.html#addStretch">addStretch()</a> and not using it.</p>
<p class="centerAlign"><img src="images/addressbook-tutorial-part2-stretch-effects.png" alt="" /></p><p>We then add <tt>buttonLayout1</tt> to <tt>mainLayout</tt>, using <a href="qgridlayout.html#addLayout">addLayout()</a>. This gives us nested layouts as <tt>buttonLayout1</tt> is now a child of <tt>mainLayout</tt>.</p>
<pre class="cpp">     <span class="type"><a href="qgridlayout.html">QGridLayout</a></span> <span class="operator">*</span>mainLayout <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qgridlayout.html">QGridLayout</a></span>;
     mainLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(nameLabel<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">0</span>);
     mainLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(nameLine<span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="number">1</span>);
     mainLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(addressLabel<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">0</span><span class="operator">,</span> <span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>AlignTop);
     mainLayout<span class="operator">-</span><span class="operator">&gt;</span>addWidget(addressText<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">1</span>);
     mainLayout<span class="operator">-</span><span class="operator">&gt;</span>addLayout(buttonLayout1<span class="operator">,</span> <span class="number">1</span><span class="operator">,</span> <span class="number">2</span>);</pre>
<p>Our layout coordinates now look like this:</p>
<p class="centerAlign"><img src="images/addressbook-tutorial-part2-labeled-layout.png" alt="" /></p><p>In the <tt>addContact()</tt> function, we store the last displayed contact details in <tt>oldName</tt> and <tt>oldAddress</tt>. Then we clear these input fields and turn off the read-only mode. The focus is set on <tt>nameLine</tt> and we display <tt>submitButton</tt> and <tt>cancelButton</tt>.</p>
<pre class="cpp"> <span class="type">void</span> AddressBook<span class="operator">::</span>addContact()
 {
     oldName <span class="operator">=</span> nameLine<span class="operator">-</span><span class="operator">&gt;</span>text();
     oldAddress <span class="operator">=</span> addressText<span class="operator">-</span><span class="operator">&gt;</span>toPlainText();

     nameLine<span class="operator">-</span><span class="operator">&gt;</span>clear();
     addressText<span class="operator">-</span><span class="operator">&gt;</span>clear();

     nameLine<span class="operator">-</span><span class="operator">&gt;</span>setReadOnly(<span class="keyword">false</span>);
     nameLine<span class="operator">-</span><span class="operator">&gt;</span>setFocus(<span class="type"><a href="qt.html">Qt</a></span><span class="operator">::</span>OtherFocusReason);
     addressText<span class="operator">-</span><span class="operator">&gt;</span>setReadOnly(<span class="keyword">false</span>);

     addButton<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">false</span>);
     submitButton<span class="operator">-</span><span class="operator">&gt;</span>show();
     cancelButton<span class="operator">-</span><span class="operator">&gt;</span>show();
 }</pre>
<p>The <tt>submitContact()</tt> function can be divided into three parts:</p>
<ol class="1">
<li>We extract the contact's details from <tt>nameLine</tt> and <tt>addressText</tt> and store them in <a href="qstring.html">QString</a> objects. We also validate to make sure that the user did not click <b>Submit</b> with empty input fields; otherwise, a <a href="qmessagebox.html">QMessageBox</a> is displayed to remind the user for a name and address.<pre class="cpp"> <span class="type">void</span> AddressBook<span class="operator">::</span>submitContact()
 {
     <span class="type"><a href="qstring.html">QString</a></span> name <span class="operator">=</span> nameLine<span class="operator">-</span><span class="operator">&gt;</span>text();
     <span class="type"><a href="qstring.html">QString</a></span> address <span class="operator">=</span> addressText<span class="operator">-</span><span class="operator">&gt;</span>toPlainText();

     <span class="keyword">if</span> (name<span class="operator">.</span>isEmpty() <span class="operator">|</span><span class="operator">|</span> address<span class="operator">.</span>isEmpty()) {
         <span class="type"><a href="qmessagebox.html">QMessageBox</a></span><span class="operator">::</span>information(<span class="keyword">this</span><span class="operator">,</span> tr(<span class="string">&quot;Empty Field&quot;</span>)<span class="operator">,</span>
             tr(<span class="string">&quot;Please enter a name and address.&quot;</span>));
         <span class="keyword">return</span>;
     }</pre>
</li>
<li>We then proceed to check if the contact already exists. If it does not exist, we add the contact to <tt>contacts</tt> and we display a <a href="qmessagebox.html">QMessageBox</a> to inform the user that the contact has been added.<pre class="cpp">     <span class="keyword">if</span> (<span class="operator">!</span>contacts<span class="operator">.</span>contains(name)) {
         contacts<span class="operator">.</span>insert(name<span class="operator">,</span> address);
         <span class="type"><a href="qmessagebox.html">QMessageBox</a></span><span class="operator">::</span>information(<span class="keyword">this</span><span class="operator">,</span> tr(<span class="string">&quot;Add Successful&quot;</span>)<span class="operator">,</span>
             tr(<span class="string">&quot;\&quot;%1\&quot; has been added to your address book.&quot;</span>)<span class="operator">.</span>arg(name));
     } <span class="keyword">else</span> {
         <span class="type"><a href="qmessagebox.html">QMessageBox</a></span><span class="operator">::</span>information(<span class="keyword">this</span><span class="operator">,</span> tr(<span class="string">&quot;Add Unsuccessful&quot;</span>)<span class="operator">,</span>
             tr(<span class="string">&quot;Sorry, \&quot;%1\&quot; is already in your address book.&quot;</span>)<span class="operator">.</span>arg(name));
         <span class="keyword">return</span>;
     }</pre>
<p>If the contact already exists, again, we display a <a href="qmessagebox.html">QMessageBox</a> to inform the user about this, preventing the user from adding duplicate contacts. Our <tt>contacts</tt> object is based on key-value pairs of name and address, hence, we want to ensure that <i>key</i> is unique.</p>
</li>
<li>Once we have handled both cases mentioned above, we restore the push buttons to their normal state with the following code:<pre class="cpp">     <span class="keyword">if</span> (contacts<span class="operator">.</span>isEmpty()) {
         nameLine<span class="operator">-</span><span class="operator">&gt;</span>clear();
         addressText<span class="operator">-</span><span class="operator">&gt;</span>clear();
     }

     nameLine<span class="operator">-</span><span class="operator">&gt;</span>setReadOnly(<span class="keyword">true</span>);
     addressText<span class="operator">-</span><span class="operator">&gt;</span>setReadOnly(<span class="keyword">true</span>);
     addButton<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">true</span>);
     submitButton<span class="operator">-</span><span class="operator">&gt;</span>hide();
     cancelButton<span class="operator">-</span><span class="operator">&gt;</span>hide();
 }</pre>
</li>
</ol>
<p>The screenshot below shows the <a href="qmessagebox.html">QMessageBox</a> object we use to display information messages to the user.</p>
<p class="centerAlign"><img src="images/addressbook-tutorial-part2-add-successful.png" alt="" /></p><p>The <tt>cancel()</tt> function restores the last displayed contact details and enables <tt>addButton</tt>, as well as hides <tt>submitButton</tt> and <tt>cancelButton</tt>.</p>
<pre class="cpp"> <span class="type">void</span> AddressBook<span class="operator">::</span>cancel()
 {
     nameLine<span class="operator">-</span><span class="operator">&gt;</span>setText(oldName);
     nameLine<span class="operator">-</span><span class="operator">&gt;</span>setReadOnly(<span class="keyword">true</span>);

     addressText<span class="operator">-</span><span class="operator">&gt;</span>setText(oldAddress);
     addressText<span class="operator">-</span><span class="operator">&gt;</span>setReadOnly(<span class="keyword">true</span>);

     addButton<span class="operator">-</span><span class="operator">&gt;</span>setEnabled(<span class="keyword">true</span>);
     submitButton<span class="operator">-</span><span class="operator">&gt;</span>hide();
     cancelButton<span class="operator">-</span><span class="operator">&gt;</span>hide();
 }</pre>
<p>The general idea behind adding a contact is to give the user the flexibility to click <b>Submit</b> or <b>Cancel</b> at any time. The flowchart below further explains this concept:</p>
<p class="centerAlign"><img src="images/addressbook-tutorial-part2-add-flowchart.png" alt="" /></p></div>
<!-- @@@tutorials/addressbook/part2 -->
  <div class="ft">
    <span></span>
  </div>
</div> 
<div class="footer">
    <p>
      <acronym title="Copyright">&copy;</acronym> 2012 Nokia Corporation and/or its
      subsidiaries. Documentation contributions included herein are the copyrights of
      their respective owners.</p>
    <br />
    <p>
      The documentation provided herein is licensed under the terms of the
      <a href="http://www.gnu.org/licenses/fdl.html">GNU Free Documentation
      License version 1.3</a> as published by the Free Software Foundation.</p>
    <p>
      Documentation sources may be obtained from <a href="http://www.qt-project.org">
      www.qt-project.org</a>.</p>
    <br />
    <p>
      Nokia, Qt and their respective logos are trademarks of Nokia Corporation 
      in Finland and/or other countries worldwide. All other trademarks are property
      of their respective owners. <a title="Privacy Policy"
      href="http://en.gitorious.org/privacy_policy/">Privacy Policy</a></p>
</div>
</body>
</html>