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
|
<?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 3 - Navigating between Entries</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 3 - Navigating between Entries</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 3 - Navigating between Entries</h1>
<span class="subtitle"></span>
<!-- $$$tutorials/addressbook/part3-description -->
<div class="descr"> <a name="details"></a>
<p>Files:</p>
<ul>
<li><a href="tutorials-addressbook-part3-addressbook-cpp.html">tutorials/addressbook/part3/addressbook.cpp</a></li>
<li><a href="tutorials-addressbook-part3-addressbook-h.html">tutorials/addressbook/part3/addressbook.h</a></li>
<li><a href="tutorials-addressbook-part3-main-cpp.html">tutorials/addressbook/part3/main.cpp</a></li>
<li><a href="tutorials-addressbook-part3-part3-pro.html">tutorials/addressbook/part3/part3.pro</a></li>
</ul>
<p>The address book is now about half complete. We should add the capability to navigate among the contacts, but first we must decide what sort of a data structure we need for containing these contacts.</p>
<p>In the previous section, we used a <a href="qmap.html">QMap</a> of key-value pairs with the contact's name as the <i>key</i>, and the contact's address as the <i>value</i>. This works well for our case. However, in order to navigate and display each entry, a little bit of enhancement is needed.</p>
<p>We enhance the <a href="qmap.html">QMap</a> 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.</p>
<p class="centerAlign"><img src="images/addressbook-tutorial-part3-linkedlist.png" alt="" /></p><a name="defining-the-addressbook-class"></a>
<h2>Defining the AddressBook Class</h2>
<p>To add navigation functions to the address book, we must add two more slots to the <tt>AddressBook</tt> class: <tt>next()</tt> and <tt>previous()</tt> to the <tt>addressbook.h</tt> file:</p>
<pre class="cpp"> <span class="type">void</span> next();
<span class="type">void</span> previous();</pre>
<p>We also require another two <a href="qpushbutton.html">QPushButton</a> objects, so we declare <tt>nextButton</tt> and <tt>previousButton</tt> as private variables:</p>
<pre class="cpp"> <span class="type"><a href="qpushbutton.html">QPushButton</a></span> <span class="operator">*</span>nextButton;
<span class="type"><a href="qpushbutton.html">QPushButton</a></span> <span class="operator">*</span>previousButton;</pre>
<a name="implementing-the-addressbook-class"></a>
<h2>Implementing the AddressBook Class</h2>
<p>In the <tt>AddressBook</tt> constructor in <tt>addressbook.cpp</tt>, we instantiate <tt>nextButton</tt> and <tt>previousButton</tt> and disable them by default. This is because navigation is only enabled when there is more than one contact in the address book.</p>
<pre class="cpp"> nextButton <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qpushbutton.html">QPushButton</a></span>(tr(<span class="string">"&Next"</span>));
nextButton<span class="operator">-</span><span class="operator">></span>setEnabled(<span class="keyword">false</span>);
previousButton <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qpushbutton.html">QPushButton</a></span>(tr(<span class="string">"&Previous"</span>));
previousButton<span class="operator">-</span><span class="operator">></span>setEnabled(<span class="keyword">false</span>);</pre>
<p>We then connect these push buttons to their respective slots:</p>
<pre class="cpp"> connect(nextButton<span class="operator">,</span> SIGNAL(clicked())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(next()));
connect(previousButton<span class="operator">,</span> SIGNAL(clicked())<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(previous()));</pre>
<p>The image below is the expected graphical user interface.</p>
<p class="centerAlign"><img src="images/addressbook-tutorial-part3-screenshot.png" alt="" /></p><p>We follow basic conventions for <tt>next()</tt> and <tt>previous()</tt> functions by placing the <tt>nextButton</tt> on the right and the <tt>previousButton</tt> on the left. In order to achieve this intuitive layout, we use <a href="qhboxlayout.html">QHBoxLayout</a> to place the widgets side-by-side:</p>
<pre class="cpp"> <span class="type"><a href="qhboxlayout.html">QHBoxLayout</a></span> <span class="operator">*</span>buttonLayout2 <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qhboxlayout.html">QHBoxLayout</a></span>;
buttonLayout2<span class="operator">-</span><span class="operator">></span>addWidget(previousButton);
buttonLayout2<span class="operator">-</span><span class="operator">></span>addWidget(nextButton);</pre>
<p>The <a href="qhboxlayout.html">QHBoxLayout</a> object, <tt>buttonLayout2</tt>, is then added to <tt>mainLayout</tt>.</p>
<pre class="cpp"> mainLayout<span class="operator">-</span><span class="operator">></span>addLayout(buttonLayout2<span class="operator">,</span> <span class="number">2</span><span class="operator">,</span> <span class="number">1</span>);</pre>
<p>The figure below shows the coordinates of the widgets in <tt>mainLayout</tt>.</p>
<p class="centerAlign"><img src="images/addressbook-tutorial-part3-labeled-layout.png" alt="" /></p><p>Within our <tt>addContact()</tt> function, we have to disable these buttons so that the user does not attempt to navigate while adding a contact.</p>
<pre class="cpp"> nextButton<span class="operator">-</span><span class="operator">></span>setEnabled(<span class="keyword">false</span>);
previousButton<span class="operator">-</span><span class="operator">></span>setEnabled(<span class="keyword">false</span>);</pre>
<p>Also, in our <tt>submitContact()</tt> function, we enable the navigation buttons, <tt>nextButton</tt> and <tt>previousButton</tt>, depending on the size of <tt>contacts</tt>. As mentioned 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:</p>
<pre class="cpp"> <span class="type">int</span> number <span class="operator">=</span> contacts<span class="operator">.</span>size();
nextButton<span class="operator">-</span><span class="operator">></span>setEnabled(number <span class="operator">></span> <span class="number">1</span>);
previousButton<span class="operator">-</span><span class="operator">></span>setEnabled(number <span class="operator">></span> <span class="number">1</span>);</pre>
<p>We also include these lines of code in the <tt>cancel()</tt> function.</p>
<p>Recall that we intend to emulate a circularly-linked list with our <a href="qmap.html">QMap</a> object, <tt>contacts</tt>. So, in the <tt>next()</tt> function, we obtain an iterator for <tt>contacts</tt> and then:</p>
<ul>
<li>If the iterator is not at the end of <tt>contacts</tt>, we increment it by one.</li>
<li>If the iterator is at the end of <tt>contacts</tt>, we move it to the beginning of <tt>contacts</tt>. This gives us the illusion that our <a href="qmap.html">QMap</a> is working like a circularly-linked list.</li>
</ul>
<pre class="cpp"> <span class="type">void</span> AddressBook<span class="operator">::</span>next()
{
<span class="type"><a href="qstring.html">QString</a></span> name <span class="operator">=</span> nameLine<span class="operator">-</span><span class="operator">></span>text();
<span class="type"><a href="qmap.html">QMap</a></span><span class="operator"><</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">></span><span class="operator">::</span>iterator i <span class="operator">=</span> contacts<span class="operator">.</span>find(name);
<span class="keyword">if</span> (i <span class="operator">!</span><span class="operator">=</span> contacts<span class="operator">.</span>end())
i<span class="operator">+</span><span class="operator">+</span>;
<span class="keyword">if</span> (i <span class="operator">=</span><span class="operator">=</span> contacts<span class="operator">.</span>end())
i <span class="operator">=</span> contacts<span class="operator">.</span>begin();
nameLine<span class="operator">-</span><span class="operator">></span>setText(i<span class="operator">.</span>key());
addressText<span class="operator">-</span><span class="operator">></span>setText(i<span class="operator">.</span>value());
}</pre>
<p>Once we have iterated to the correct object in <tt>contacts</tt>, we display its contents on <tt>nameLine</tt> and <tt>addressText</tt>.</p>
<p>Similarly, for the <tt>previous()</tt> function, we obtain an iterator for <tt>contacts</tt> and then:</p>
<ul>
<li>If the iterator is at the end of <tt>contacts</tt>, we clear the display and return.</li>
<li>If the iterator is at the beginning of <tt>contacts</tt>, we move it to the end.</li>
<li>We then decrement the iterator by one.</li>
</ul>
<pre class="cpp"> <span class="type">void</span> AddressBook<span class="operator">::</span>previous()
{
<span class="type"><a href="qstring.html">QString</a></span> name <span class="operator">=</span> nameLine<span class="operator">-</span><span class="operator">></span>text();
<span class="type"><a href="qmap.html">QMap</a></span><span class="operator"><</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">></span><span class="operator">::</span>iterator i <span class="operator">=</span> contacts<span class="operator">.</span>find(name);
<span class="keyword">if</span> (i <span class="operator">=</span><span class="operator">=</span> contacts<span class="operator">.</span>end()){
nameLine<span class="operator">-</span><span class="operator">></span>clear();
addressText<span class="operator">-</span><span class="operator">></span>clear();
<span class="keyword">return</span>;
}
<span class="keyword">if</span> (i <span class="operator">=</span><span class="operator">=</span> contacts<span class="operator">.</span>begin())
i <span class="operator">=</span> contacts<span class="operator">.</span>end();
i<span class="operator">-</span><span class="operator">-</span>;
nameLine<span class="operator">-</span><span class="operator">></span>setText(i<span class="operator">.</span>key());
addressText<span class="operator">-</span><span class="operator">></span>setText(i<span class="operator">.</span>value());
}</pre>
<p>Again, we display the contents of the current object in <tt>contacts</tt>.</p>
</div>
<!-- @@@tutorials/addressbook/part3 -->
<div class="ft">
<span></span>
</div>
</div>
<div class="footer">
<p>
<acronym title="Copyright">©</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>
|