Sophie

Sophie

distrib > Mageia > 5 > i586 > media > core-release > by-pkgid > 50facae208d4a6f280e44a513b104320 > files > 1936

qt-mobility-doc-1.2.0-13.mga5.noarch.rpm

<?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" />
<!-- mapsdemo.qdoc -->
  <title>Qt Mobility 1.2: Part 3 - Listening to satellites</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>QtMobility Reference Documentation</span></a>
  </div>
  <div class="breadcrumb toolblock">
    <ul>
      <li class="first"><a href="index.html">Home</a></li>
      <!--  Breadcrumbs go here -->
<li>Part 3 - Listening to satellites</li>
    </ul>
  </div>
</div>
<div class="content mainContent">
  <link rel="prev" href="tutorials-mapsdemo-part2.html" />
  <link rel="next" href="tutorials-mapsdemo-part4.html" />
  <link rel="start" href="tutorials-mapsdemo.html" />
<p class="naviNextPrevious headerNavi">
<a class="prevPage" href="tutorials-mapsdemo-part2.html">Part 2 - Searching for locations</a>
<a class="nextPage" href="tutorials-mapsdemo-part4.html">Part 4 - Stopping for directions</a>
</p><p/>
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level2"><a href="#animated-status-bar">Animated status bar</a></li>
<li class="level2"><a href="#getting-gps-data">Getting GPS data</a></li>
<li class="level2"><a href="#following-and-animated-panning">Following and animated panning</a></li>
</ul>
</div>
<h1 class="title">Part 3 - Listening to satellites</h1>
<span class="subtitle"></span>
<!-- $$$tutorials-mapsdemo-part3.html-description -->
<div class="descr"> <a name="details"></a>
<p>Another useful part of the Location API is the ability to receive updates of the user's present geographic location from methods such as GPS or network positioning. We're going to add support to our MapsDemo for using these methods to update the &quot;my location&quot; marker we've already added in parts 1 and 2 of this tutorial.</p>
<p>But first we need an attractive way to present status messages to the user while they are busy looking at the map. We're going to do this using an animated translucent rectangle at the bottom of the display.</p>
<a name="animated-status-bar"></a>
<h3>Animated status bar</h3>
<p>First, set up the map to resize automatically:</p>
<pre class="cpp"> <span class="keyword">class</span> MapsWidget : <span class="keyword">public</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qwidget.html">QWidget</a></span>
 {
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
 <span class="keyword">private</span>:
     <span class="type">void</span> resizeEvent(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qresizeevent.html">QResizeEvent</a></span> <span class="operator">*</span>event);
     <span class="type">void</span> showEvent(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qshowevent.html">QShowEvent</a></span> <span class="operator">*</span>event);
 };

 <span class="type">void</span> MapsWidget<span class="operator">::</span>resizeEvent(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qresizeevent.html">QResizeEvent</a></span> <span class="operator">*</span>event)
 {
     <span class="keyword">if</span> (d<span class="operator">-</span><span class="operator">&gt;</span>view <span class="operator">&amp;</span><span class="operator">&amp;</span> d<span class="operator">-</span><span class="operator">&gt;</span>map) {
         d<span class="operator">-</span><span class="operator">&gt;</span>view<span class="operator">-</span><span class="operator">&gt;</span>resize(size());
         d<span class="operator">-</span><span class="operator">&gt;</span>map<span class="operator">-</span><span class="operator">&gt;</span>resize(size());
         d<span class="operator">-</span><span class="operator">&gt;</span>view<span class="operator">-</span><span class="operator">&gt;</span>centerOn(d<span class="operator">-</span><span class="operator">&gt;</span>map);
     }
 }

 <span class="type">void</span> MapsWidget<span class="operator">::</span>showEvent(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qshowevent.html">QShowEvent</a></span> <span class="operator">*</span>event)
 {
     <span class="keyword">if</span> (d<span class="operator">-</span><span class="operator">&gt;</span>view <span class="operator">&amp;</span><span class="operator">&amp;</span> d<span class="operator">-</span><span class="operator">&gt;</span>map) {
         d<span class="operator">-</span><span class="operator">&gt;</span>view<span class="operator">-</span><span class="operator">&gt;</span>resize(size());
         d<span class="operator">-</span><span class="operator">&gt;</span>map<span class="operator">-</span><span class="operator">&gt;</span>resize(size());
         d<span class="operator">-</span><span class="operator">&gt;</span>view<span class="operator">-</span><span class="operator">&gt;</span>centerOn(d<span class="operator">-</span><span class="operator">&gt;</span>map);
     }
 }</pre>
<p>And now we add our new StatusBarItem class:</p>
<pre class="cpp"> <span class="keyword">class</span> StatusBarItemPrivate;
 <span class="keyword">class</span> StatusBarItem : <span class="keyword">public</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qobject.html">QObject</a></span><span class="operator">,</span> <span class="keyword">public</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsrectitem.html">QGraphicsRectItem</a></span>
 {
     Q_OBJECT
     Q_PROPERTY(<span class="type">int</span> offset READ offset WRITE setOffset)

 <span class="keyword">public</span>:
     StatusBarItem();
     <span class="operator">~</span>StatusBarItem();

     <span class="type">int</span> offset() <span class="keyword">const</span>;
     <span class="type">void</span> setRect(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qtglobal.html#qreal-typedef">qreal</a></span> x<span class="operator">,</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qtglobal.html#qreal-typedef">qreal</a></span> y<span class="operator">,</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qtglobal.html#qreal-typedef">qreal</a></span> w<span class="operator">,</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qtglobal.html#qreal-typedef">qreal</a></span> h);

 <span class="keyword">public</span> <span class="keyword">slots</span>:
     <span class="type">void</span> setText(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qstring.html">QString</a></span> text);

     <span class="type">void</span> showText(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qstring.html">QString</a></span> text<span class="operator">,</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qtglobal.html#quint32-typedef">quint32</a></span> timeout<span class="operator">=</span><span class="number">3000</span>);
     <span class="type">void</span> show();
     <span class="type">void</span> hide();

     <span class="type">void</span> setOffset(<span class="type">int</span> offset);

 <span class="keyword">private</span>:
     StatusBarItemPrivate <span class="operator">*</span>d;
 };</pre>
<p>Note that the order of base classes here is very important: <a href="http://qt.nokia.com/doc/4.7/qobject.html">QObject</a> and then <a href="http://qt.nokia.com/doc/4.7/qgraphicsrectitem.html">QGraphicsRectItem</a>. Re-ordering the base classes will cause the code not to compile, as <a href="http://qt.nokia.com/doc/4.7/qgraphicsrectitem.html">QGraphicsRectItem</a> does not have a meta-object (for more details consult the documentation in Qt).</p>
<p>The <i>offset</i> property here is added so that when we come to animating our status bar, we can handle the case where the bar is sliding in and the window is being resized simultaneously. If we simply animated the <i>y</i> property of the GraphicsItem instead we would have difficulty handling this case.</p>
<p>Now add a pointer to one of these in MapsWidgetPrivate (and matching accessor methods):</p>
<pre class="cpp"> <span class="keyword">class</span> MapsWidgetPrivate
 {
 <span class="keyword">public</span>:
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
     StatusBarItem <span class="operator">*</span>statusBarItem;
 };</pre>
<p>And we're ready for the implementation. The constructor is not terribly exciting, but sets the defaults for everything:</p>
<pre class="cpp"> <span class="keyword">class</span> StatusBarItemPrivate
 {
 <span class="keyword">public</span>:
     <span class="type">int</span> offset;
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicssimpletextitem.html">QGraphicsSimpleTextItem</a></span> <span class="operator">*</span>textItem;
 };

 StatusBarItem<span class="operator">::</span>StatusBarItem() :
     d(<span class="keyword">new</span> StatusBarItemPrivate)
 {
     d<span class="operator">-</span><span class="operator">&gt;</span>offset <span class="operator">=</span> <span class="number">0</span>;

     setPen(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qpen.html">QPen</a></span>(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qbrush.html">QBrush</a></span>()<span class="operator">,</span> <span class="number">0</span>));
     setBrush(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qbrush.html">QBrush</a></span>(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qcolor.html">QColor</a></span>(<span class="number">0</span><span class="operator">,</span><span class="number">0</span><span class="operator">,</span><span class="number">0</span><span class="operator">,</span><span class="number">120</span>)));

     d<span class="operator">-</span><span class="operator">&gt;</span>textItem <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicssimpletextitem.html">QGraphicsSimpleTextItem</a></span>(<span class="keyword">this</span>);
     d<span class="operator">-</span><span class="operator">&gt;</span>textItem<span class="operator">-</span><span class="operator">&gt;</span>setBrush(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qbrush.html">QBrush</a></span>(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qt.html">Qt</a></span><span class="operator">::</span>white));

     setText(<span class="string">&quot;&quot;</span>);
 }</pre>
<p>The <i>setText</i> function, however, is more interesting;</p>
<pre class="cpp"> <span class="type">void</span> StatusBarItem<span class="operator">::</span>setText(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qstring.html">QString</a></span> text)
 {
     d<span class="operator">-</span><span class="operator">&gt;</span>textItem<span class="operator">-</span><span class="operator">&gt;</span>setText(text);
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qrectf.html">QRectF</a></span> rect <span class="operator">=</span> d<span class="operator">-</span><span class="operator">&gt;</span>textItem<span class="operator">-</span><span class="operator">&gt;</span>boundingRect();
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qpointf.html">QPointF</a></span> delta <span class="operator">=</span> <span class="keyword">this</span><span class="operator">-</span><span class="operator">&gt;</span>rect()<span class="operator">.</span>center() <span class="operator">-</span> rect<span class="operator">.</span>center();
     d<span class="operator">-</span><span class="operator">&gt;</span>textItem<span class="operator">-</span><span class="operator">&gt;</span>setPos(delta<span class="operator">.</span>x()<span class="operator">,</span> delta<span class="operator">.</span>y());
 }</pre>
<p>This re-centers the <i>textItem</i> inside its parent (the StatusBarItem) every time the text changes.</p>
<p>Also, the <i>setRect</i> method is used to update the size and position of the status bar:</p>
<pre class="cpp"> <span class="type">void</span> StatusBarItem<span class="operator">::</span>setRect(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qtglobal.html#qreal-typedef">qreal</a></span> x<span class="operator">,</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qtglobal.html#qreal-typedef">qreal</a></span> y<span class="operator">,</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qtglobal.html#qreal-typedef">qreal</a></span> w<span class="operator">,</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qtglobal.html#qreal-typedef">qreal</a></span> h)
 {
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsrectitem.html">QGraphicsRectItem</a></span><span class="operator">::</span>setRect(x<span class="operator">,</span> y <span class="operator">+</span> d<span class="operator">-</span><span class="operator">&gt;</span>offset<span class="operator">,</span> w<span class="operator">,</span> h);
     setText(d<span class="operator">-</span><span class="operator">&gt;</span>textItem<span class="operator">-</span><span class="operator">&gt;</span>text());
 }</pre>
<p>Here we see the use of the <i>offset</i> property for the first time. The idea is to call <i>setRect</i> to specify a rectangle that is below the bottom of the visible area in the <a href="http://qt.nokia.com/doc/4.7/qgraphicsview.html">QGraphicsView</a>. Then <i>offset</i> is used to bump the status bar up into the visible area when needed.</p>
<p>Whenever we change the offset we should re-calculate our own <i>y</i> value using the rect and the offset together:</p>
<pre class="cpp"> <span class="type">void</span> StatusBarItem<span class="operator">::</span>setOffset(<span class="type">int</span> offset)
 {
     <span class="keyword">this</span><span class="operator">-</span><span class="operator">&gt;</span>setY(<span class="keyword">this</span><span class="operator">-</span><span class="operator">&gt;</span>y() <span class="operator">-</span> d<span class="operator">-</span><span class="operator">&gt;</span>offset <span class="operator">+</span> offset);
     d<span class="operator">-</span><span class="operator">&gt;</span>offset <span class="operator">=</span> offset;
 }</pre>
<p>And now finally, the animations:</p>
<pre class="cpp"> <span class="type">void</span> StatusBarItem<span class="operator">::</span>show()
 {
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qpropertyanimation.html">QPropertyAnimation</a></span> <span class="operator">*</span>anim <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qpropertyanimation.html">QPropertyAnimation</a></span>(<span class="keyword">this</span><span class="operator">,</span> <span class="string">&quot;offset&quot;</span>);
     anim<span class="operator">-</span><span class="operator">&gt;</span>setStartValue(<span class="number">0</span>);
     anim<span class="operator">-</span><span class="operator">&gt;</span>setEndValue(<span class="operator">-</span><span class="number">1</span> <span class="operator">*</span> rect()<span class="operator">.</span>height());
     anim<span class="operator">-</span><span class="operator">&gt;</span>setDuration(<span class="number">500</span>);
     anim<span class="operator">-</span><span class="operator">&gt;</span>start(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qabstractanimation.html">QAbstractAnimation</a></span><span class="operator">::</span>DeleteWhenStopped);
 }

 <span class="type">void</span> StatusBarItem<span class="operator">::</span>hide()
 {
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qpropertyanimation.html">QPropertyAnimation</a></span> <span class="operator">*</span>anim <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qpropertyanimation.html">QPropertyAnimation</a></span>(<span class="keyword">this</span><span class="operator">,</span> <span class="string">&quot;offset&quot;</span>);
     anim<span class="operator">-</span><span class="operator">&gt;</span>setStartValue(d<span class="operator">-</span><span class="operator">&gt;</span>offset);
     anim<span class="operator">-</span><span class="operator">&gt;</span>setEndValue(<span class="number">0</span>);
     anim<span class="operator">-</span><span class="operator">&gt;</span>setDuration(<span class="number">500</span>);
     anim<span class="operator">-</span><span class="operator">&gt;</span>start(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qabstractanimation.html">QAbstractAnimation</a></span><span class="operator">::</span>DeleteWhenStopped);
 }</pre>
<p>You can see here that we simply use QPropertyAnimations on the <i>offset</i> property we just defined. This produces a nice linear slide in and out whenever <i>show()</i> or <i>hide()</i> are called.</p>
<p>Lastly, one convenience method:</p>
<pre class="cpp"> <span class="type">void</span> StatusBarItem<span class="operator">::</span>showText(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qstring.html">QString</a></span> text<span class="operator">,</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qtglobal.html#quint32-typedef">quint32</a></span> timeout)
 {
     setText(text);
     show();
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qtimer.html">QTimer</a></span><span class="operator">::</span>singleShot(timeout<span class="operator">,</span> <span class="keyword">this</span><span class="operator">,</span> SLOT(hide()));
 }</pre>
<p>This lets us more easily display a status message when we only want it to appear and disappear soon afterwards.</p>
<p>Then we have only to add this into our MapsWidget:</p>
<pre class="cpp"> <span class="type">void</span> MapsWidget<span class="operator">::</span>initialize(<span class="type"><a href="qgeomappingmanager.html">QGeoMappingManager</a></span> <span class="operator">*</span>manager)
 {
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsscene.html">QGraphicsScene</a></span> <span class="operator">*</span>sc;
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
     d<span class="operator">-</span><span class="operator">&gt;</span>statusBarItem <span class="operator">=</span> <span class="keyword">new</span> StatusBarItem;
     sc<span class="operator">-</span><span class="operator">&gt;</span>addItem(d<span class="operator">-</span><span class="operator">&gt;</span>statusBarItem);
 }

 <span class="type">void</span> MapsWidget<span class="operator">::</span>resizeEvent(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qresizeevent.html">QResizeEvent</a></span> <span class="operator">*</span>event)
 {
     <span class="keyword">if</span> (d<span class="operator">-</span><span class="operator">&gt;</span>view <span class="operator">&amp;</span><span class="operator">&amp;</span> d<span class="operator">-</span><span class="operator">&gt;</span>map) {
         <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
         d<span class="operator">-</span><span class="operator">&gt;</span>statusBarItem<span class="operator">-</span><span class="operator">&gt;</span>setRect(<span class="number">0</span><span class="operator">,</span> height()<span class="operator">,</span> width()<span class="operator">,</span> <span class="number">20</span>);
     }
 }

 <span class="comment">// and similarly in MapsWidget::showEvent()</span></pre>
<a name="getting-gps-data"></a>
<h3>Getting GPS data</h3>
<p>Now we move on to the focus of this section: GPS data and how to get it. The <a href="qgeopositioninfosource.html">QGeoPositionInfoSource</a> class gives a convenient interface to receive position updates. We're going to add one to our <a href="http://qt.nokia.com/doc/4.7/designer-to-know.html">MainWindow</a>:</p>
<pre class="cpp"> <span class="keyword">class</span> MainWindow : <span class="keyword">public</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qmainwindow.html">QMainWindow</a></span>
 {
 <span class="keyword">private</span>:
     <span class="type"><a href="qgeopositioninfosource.html">QGeoPositionInfoSource</a></span> <span class="operator">*</span>positionSource;

 <span class="keyword">private</span> <span class="keyword">slots</span>:
     <span class="comment">// slot to receive updates</span>
     <span class="type">void</span> updateMyPosition(<span class="type"><a href="qgeopositioninfo.html">QGeoPositionInfo</a></span> info);
 };</pre>
<p>And in <i>initialize()</i> we'll set it up. We're just using whatever the default position source for the platform happens to be, at an update interval of 1000ms, which is plenty for a basic maps application. Once set up, we call the source's <i>startUpdates()</i> method to begin receiving position updates.</p>
<pre class="cpp"> <span class="type">void</span> MainWindow<span class="operator">::</span>initialize()
 {
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
     <span class="keyword">if</span> (positionSource)
         <span class="keyword">delete</span> positionSource;

     positionSource <span class="operator">=</span> <span class="type"><a href="qgeopositioninfosource.html">QGeoPositionInfoSource</a></span><span class="operator">::</span>createDefaultSource(<span class="keyword">this</span>);

     <span class="keyword">if</span> (<span class="operator">!</span>positionSource) {
         mapsWidget<span class="operator">-</span><span class="operator">&gt;</span>statusBar()<span class="operator">-</span><span class="operator">&gt;</span>showText(<span class="string">&quot;Could not open GPS&quot;</span><span class="operator">,</span> <span class="number">5000</span>);
         mapsWidget<span class="operator">-</span><span class="operator">&gt;</span>setMyLocation(<span class="type"><a href="qgeocoordinate.html">QGeoCoordinate</a></span>(<span class="operator">-</span><span class="number">27.5796</span><span class="operator">,</span> <span class="number">153.1</span>));
     } <span class="keyword">else</span> {
         positionSource<span class="operator">-</span><span class="operator">&gt;</span>setUpdateInterval(<span class="number">1000</span>);
         connect(positionSource<span class="operator">,</span> SIGNAL(positionUpdated(<span class="type"><a href="qgeopositioninfo.html">QGeoPositionInfo</a></span>))<span class="operator">,</span>
                 <span class="keyword">this</span><span class="operator">,</span> SLOT(updateMyPosition(<span class="type"><a href="qgeopositioninfo.html">QGeoPositionInfo</a></span>)));
         positionSource<span class="operator">-</span><span class="operator">&gt;</span>startUpdates();
         mapsWidget<span class="operator">-</span><span class="operator">&gt;</span>statusBar()<span class="operator">-</span><span class="operator">&gt;</span>showText(<span class="string">&quot;Opening GPS...&quot;</span>);
     }
 }</pre>
<p>Here we also make use of the StatusBarItem to display a message when we are able or unable to open the <a href="qgeopositioninfosource.html">QGeoPositionInfoSource</a>.</p>
<p>And then in the slot <i>updateMyPosition</i>, we use this to set the myLocation marker.</p>
<pre class="cpp"> <span class="type">void</span> MainWindow<span class="operator">::</span>updateMyPosition(<span class="type"><a href="qgeopositioninfo.html">QGeoPositionInfo</a></span> info)
 {
     <span class="keyword">if</span> (mapsWidget) {
         mapsWidget<span class="operator">-</span><span class="operator">&gt;</span>setMyLocation(info<span class="operator">.</span>coordinate());
     }
 }</pre>
<p>So, running the code as is, we have a moving marker for &quot;My Location&quot; that follows our actual GPS or network-sourced location. If you start driving your car with this app running however, you'll quickly notice the fact that the viewport does not pan to follow you as you leave the map area.</p>
<p>We could simply add a call to <i>setCenter()</i> on the map object in the <i>updateMyPosition</i> slot, but in the interests of prettiness, we are going to make a nice smoothly animated transition instead.</p>
<a name="following-and-animated-panning"></a>
<h3>Following and animated panning</h3>
<p>First, add a new boolean member variable to <a href="http://qt.nokia.com/doc/4.7/designer-to-know.html">MainWindow</a>, called <i>tracking</i>, to keep track of whether the viewport is currently following the My Location marker:</p>
<pre class="cpp"> <span class="keyword">class</span> MainWindow : <span class="keyword">public</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qmainwindow.html">QMainWindow</a></span>
 {
 <span class="keyword">private</span>:
     <span class="type">bool</span> tracking;
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
 };</pre>
<p>Our intended design is that initially, the viewport will be in tracking mode. It will continue this way until the view is manually panned by the user, at which point tracking will stop. Then, if the user clicks the &quot;My Location&quot; menu option to re-center the map, we resume tracking once again.</p>
<p>So we will need a way to notify the <a href="http://qt.nokia.com/doc/4.7/designer-to-know.html">MainWindow</a> that the user has panned the view. Add a new signal <i>mapPanned()</i> to MapsWidget, and a corresponding signal <i>panned()</i> to GeoMap, as we did for <i>clicked()</i>.</p>
<pre class="cpp"> <span class="keyword">class</span> MapsWidget : <span class="keyword">public</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qwidget.html">QWidget</a></span>
 {
 <span class="keyword">signals</span>:
     <span class="type">void</span> mapPanned();
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
 };

 <span class="keyword">class</span> GeoMap : <span class="keyword">public</span> <span class="type"><a href="qgraphicsgeomap.html">QGraphicsGeoMap</a></span>
 {
 <span class="keyword">signals</span>:
     <span class="type">void</span> panned();
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
 };

 <span class="type">void</span> MapsWidget<span class="operator">::</span>initialize(<span class="type"><a href="qgeomappingmanager.html">QGeoMappingManager</a></span> <span class="operator">*</span>manager)
 {
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
     connect(geoMap<span class="operator">,</span> SIGNAL(panned())<span class="operator">,</span>
             <span class="keyword">this</span><span class="operator">,</span> SIGNAL(mapPanned()));
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
 }</pre>
<p>And now we simply emit it when a user pan takes place:</p>
<pre class="cpp"> <span class="type">void</span> GeoMap<span class="operator">::</span>mouseMoveEvent(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qgraphicsscenemouseevent.html">QGraphicsSceneMouseEvent</a></span> <span class="operator">*</span>event)
 {
     <span class="keyword">if</span> (panActive) {
         <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
         <span class="keyword">emit</span> panned();
     }
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
 }</pre>
<p>Back up in <a href="http://qt.nokia.com/doc/4.7/designer-to-know.html">MainWindow</a>, we create a slot <i>disableTracking</i> and hook up the new signal to it:</p>
<pre class="cpp"> <span class="keyword">class</span> MainWindow : <span class="keyword">public</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qmainwindow.html">QMainWindow</a></span>
 {
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
 <span class="keyword">private</span> <span class="keyword">slots</span>:
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
     <span class="type">void</span> disableTracking();
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
 };

 <span class="type">void</span> MainWindow<span class="operator">::</span>initialize()
 {
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
     connect(mapsWidget<span class="operator">,</span> SIGNAL(mapPanned())<span class="operator">,</span>
             <span class="keyword">this</span><span class="operator">,</span> SLOT(disableTracking()));
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
 }</pre>
<p>And finally in the slot itself we simply set the flag we created earlier:</p>
<pre class="cpp"> <span class="type">void</span> MainWindow<span class="operator">::</span>disableTracking()
 {
     tracking <span class="operator">=</span> <span class="keyword">false</span>;
 }</pre>
<p>Next we want animated panning to be available. Add a new method on MapsWidget:</p>
<pre class="cpp"> <span class="keyword">class</span> MapsWidget : <span class="keyword">public</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qwidget.html">QWidget</a></span>
 {
 <span class="keyword">public</span>:
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
     <span class="type">void</span> animatedPanTo(<span class="type"><a href="qgeocoordinate.html">QGeoCoordinate</a></span> center);
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
 };</pre>
<p>To do animations in Qt, it's always easiest if we can make use of a <a href="http://qt.nokia.com/doc/4.7/qpropertyanimation.html">QPropertyAnimation</a>, and to do this you need a Q_PROPERTY to act upon. We'll use two animations in parallel, one moving latitude and one moving longitude, so we need two Q_PROPERTIES:</p>
<pre class="cpp"> <span class="keyword">class</span> GeoMap : <span class="keyword">public</span> <span class="type"><a href="qgraphicsgeomap.html">QGraphicsGeoMap</a></span>
 {
     Q_OBJECT

     Q_PROPERTY(<span class="type">double</span> centerLatitude READ centerLatitude WRITE setCenterLatitude)
     Q_PROPERTY(<span class="type">double</span> centerLongitude READ centerLongitude WRITE setCenterLongitude)

 <span class="keyword">public</span>:
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
     <span class="type">double</span> centerLatitude() <span class="keyword">const</span>;
     <span class="type">void</span> setCenterLatitude(<span class="type">double</span> lat);
     <span class="type">double</span> centerLongitude() <span class="keyword">const</span>;
     <span class="type">void</span> setCenterLongitude(<span class="type">double</span> lon);
     <span class="operator">.</span><span class="operator">.</span><span class="operator">.</span>
 };</pre>
<p>These functions simply adjust the corresponding value on <i>center()</i> and then call <i>setCenter()</i> with the new <i>QGeoCoordinate</i>.</p>
<p>Now we can implement our <i>animatedPanTo()</i> method:</p>
<pre class="cpp"> <span class="type">void</span> MapsWidget<span class="operator">::</span>animatedPanTo(<span class="type"><a href="qgeocoordinate.html">QGeoCoordinate</a></span> center)
 {
     <span class="keyword">if</span> (<span class="operator">!</span>d<span class="operator">-</span><span class="operator">&gt;</span>map)
         <span class="keyword">return</span>;

     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qpropertyanimation.html">QPropertyAnimation</a></span> <span class="operator">*</span>latAnim <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qpropertyanimation.html">QPropertyAnimation</a></span>(d<span class="operator">-</span><span class="operator">&gt;</span>map<span class="operator">,</span> <span class="string">&quot;centerLatitude&quot;</span>);
     latAnim<span class="operator">-</span><span class="operator">&gt;</span>setEndValue(center<span class="operator">.</span>latitude());
     latAnim<span class="operator">-</span><span class="operator">&gt;</span>setDuration(<span class="number">200</span>);
     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qpropertyanimation.html">QPropertyAnimation</a></span> <span class="operator">*</span>lonAnim <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qpropertyanimation.html">QPropertyAnimation</a></span>(d<span class="operator">-</span><span class="operator">&gt;</span>map<span class="operator">,</span> <span class="string">&quot;centerLongitude&quot;</span>);
     lonAnim<span class="operator">-</span><span class="operator">&gt;</span>setEndValue(center<span class="operator">.</span>longitude());
     lonAnim<span class="operator">-</span><span class="operator">&gt;</span>setDuration(<span class="number">200</span>);

     <span class="type"><a href="http://qt.nokia.com/doc/4.7/qparallelanimationgroup.html">QParallelAnimationGroup</a></span> <span class="operator">*</span>group <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="http://qt.nokia.com/doc/4.7/qparallelanimationgroup.html">QParallelAnimationGroup</a></span>;
     group<span class="operator">-</span><span class="operator">&gt;</span>addAnimation(latAnim);
     group<span class="operator">-</span><span class="operator">&gt;</span>addAnimation(lonAnim);
     group<span class="operator">-</span><span class="operator">&gt;</span>start(<span class="type"><a href="http://qt.nokia.com/doc/4.7/qabstractanimation.html">QAbstractAnimation</a></span><span class="operator">::</span>DeleteWhenStopped);
 }</pre>
<p>To bring it all together, we make the last few changes in <a href="http://qt.nokia.com/doc/4.7/designer-to-know.html">MainWindow</a>:</p>
<pre class="cpp"> <span class="type">void</span> MainWindow<span class="operator">::</span>goToMyLocation()
 {
     mapsWidget<span class="operator">-</span><span class="operator">&gt;</span>animatedPanTo(markerManager<span class="operator">-</span><span class="operator">&gt;</span>myLocation());
     tracking <span class="operator">=</span> <span class="keyword">true</span>;
 }

 <span class="type">void</span> MainWindow<span class="operator">::</span>updateMyPosition(<span class="type"><a href="qgeopositioninfo.html">QGeoPositionInfo</a></span> info)
 {
     <span class="keyword">if</span> (mapsWidget) {
         mapsWidget<span class="operator">-</span><span class="operator">&gt;</span>setMyLocation(info<span class="operator">.</span>coordinate());
         <span class="keyword">if</span> (tracking)
             mapsWidget<span class="operator">-</span><span class="operator">&gt;</span>animatedPanTo(info<span class="operator">.</span>coordinate());
     }
 }</pre>
<p>And now we have the simple location tracking functionality we set out to implement.</p>
</div>
<!-- @@@tutorials-mapsdemo-part3.html -->
<p class="naviNextPrevious footerNavi">
<a class="prevPage" href="tutorials-mapsdemo-part2.html">Part 2 - Searching for locations</a>
<a class="nextPage" href="tutorials-mapsdemo-part4.html">Part 4 - Stopping for directions</a>
</p>
  <div class="ft">
    <span></span>
  </div>
</div> 
<div class="footer">
  <p>
     <acronym title="Copyright">&copy;</acronym> 2008-2011 Nokia Corporation and/or its
     subsidiaries. Nokia, Qt and their respective logos are trademarks of Nokia Corporation 
     in Finland and/or other countries worldwide.</p>
  <p>
     All other trademarks are property of their respective owners. <a title="Privacy Policy"
     href="http://qt.nokia.com/about/privacy-policy">Privacy Policy</a></p>
  <br />
  <p>
    Licensees holding valid Qt Commercial licenses may use this document in accordance with the    Qt Commercial License Agreement provided with the Software or, alternatively, in accordance    with the terms contained in a written agreement between you and Nokia.</p>
  <p>
    Alternatively, this document may be used 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>
</div>
</body>
</html>