Sophie

Sophie

distrib > Mageia > 7 > i586 > by-pkgid > 1dd17e0d683ef79b4bb6872bbf359d7f > files > 7806

qt4-doc-4.8.7-26.2.mga7.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" />
<!-- webkit-bridge-imageanalyzer.qdoc -->
  <title>Qt 4.8: The Webkit Bridge Tutorial - Hybrid Client Application</title>
  <link rel="stylesheet" type="text/css" href="style/style.css" />
  <script src="scripts/jquery.js" type="text/javascript"></script>
  <script src="scripts/functions.js" type="text/javascript"></script>
  <link rel="stylesheet" type="text/css" href="style/superfish.css" />
  <link rel="stylesheet" type="text/css" href="style/narrow.css" />
  <!--[if IE]>
<meta name="MSSmartTagsPreventParsing" content="true">
<meta http-equiv="imagetoolbar" content="no">
<![endif]-->
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie6.css">
<![endif]-->
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie7.css">
<![endif]-->
<!--[if IE 8]>
<link rel="stylesheet" type="text/css" href="style/style_ie8.css">
<![endif]-->

<script src="scripts/superfish.js" type="text/javascript"></script>
<script src="scripts/narrow.js" type="text/javascript"></script>

</head>
<body class="" onload="CheckEmptyAndLoadList();">
 <div class="header" id="qtdocheader">
    <div class="content"> 
    <div id="nav-logo">
      <a href="index.html">Home</a></div>
    <a href="index.html" class="qtref"><span>Qt Reference Documentation</span></a>
    <div id="narrowsearch"></div>
    <div id="nav-topright">
      <ul>
        <li class="nav-topright-home"><a href="http://qt.digia.com/">Qt HOME</a></li>
        <li class="nav-topright-dev"><a href="http://qt-project.org/">DEV</a></li>
        <li class="nav-topright-doc nav-topright-doc-active"><a href="http://qt-project.org/doc/">
          DOC</a></li>
        <li class="nav-topright-blog"><a href="http://blog.qt.digia.com/">BLOG</a></li>
      </ul>
    </div>
    <div id="shortCut">
      <ul>
        <li class="shortCut-topleft-inactive"><span><a href="index.html">Qt 4.8</a></span></li>
        <li class="shortCut-topleft-active"><a href="http://qt-project.org/doc/">ALL VERSIONS        </a></li>
      </ul>
     </div>
 <ul class="sf-menu" id="narrowmenu"> 
             <li><a href="#">API Lookup</a> 
                 <ul> 
                     <li><a href="classes.html">Class index</a></li> 
           <li><a href="functions.html">Function index</a></li> 
           <li><a href="modules.html">Modules</a></li> 
           <li><a href="namespaces.html">Namespaces</a></li> 
           <li><a href="qtglobal.html">Global Declarations</a></li> 
           <li><a href="qdeclarativeelements.html">QML elements</a></li> 
             </ul> 
             </li> 
             <li><a href="#">Qt Topics</a> 
                 <ul> 
                        <li><a href="qt-basic-concepts.html">Programming with Qt</a></li>  
                        <li><a href="qtquick.html">Device UIs &amp; Qt Quick</a></li>  
                        <li><a href="qt-gui-concepts.html">UI Design with Qt</a></li>  
                        <li><a href="supported-platforms.html">Supported Platforms</a></li>  
                        <li><a href="technology-apis.html">Qt and Key Technologies</a></li>  
                        <li><a href="best-practices.html">How-To's and Best Practices</a></li>  
              </ul> 
                 </li> 
                 <li><a href="#">Examples</a> 
                     <ul> 
                       <li><a href="all-examples.html">Examples</a></li> 
                       <li><a href="tutorials.html">Tutorials</a></li> 
                       <li><a href="demos.html">Demos</a></li> 
                       <li><a href="qdeclarativeexamples.html">QML Examples</a></li> 
                </ul> 
                     </li> 
                 </ul> 
    </div>
  </div>
  <div class="wrapper">
    <div class="hd">
      <span></span>
    </div>
    <div class="bd group">
      <div class="sidebar">
        <div class="searchlabel">
          Search index:</div>
        <div class="search" id="sidebarsearch">
          <form id="qtdocsearch" action="" onsubmit="return false;">
            <fieldset>
              <input type="text" name="searchstring" id="pageType" value="" />
 <div id="resultdialog"> 
 <a href="#" id="resultclose">Close</a> 
 <p id="resultlinks" class="all"><a href="#" id="showallresults">All</a> | <a href="#" id="showapiresults">API</a> | <a href="#" id="showarticleresults">Articles</a> | <a href="#" id="showexampleresults">Examples</a></p> 
 <p id="searchcount" class="all"><span id="resultcount"></span><span id="apicount"></span><span id="articlecount"></span><span id="examplecount"></span>&nbsp;results:</p> 
 <ul id="resultlist" class="all"> 
 </ul> 
 </div> 
            </fieldset>
          </form>
        </div>
        <div class="box first bottombar" id="lookup">
          <h2 title="API Lookup"><span></span>
            API Lookup</h2>
          <div  id="list001" class="list">
          <ul id="ul001" >
              <li class="defaultLink"><a href="classes.html">Class index</a></li>
              <li class="defaultLink"><a href="functions.html">Function index</a></li>
              <li class="defaultLink"><a href="modules.html">Modules</a></li>
              <li class="defaultLink"><a href="namespaces.html">Namespaces</a></li>
              <li class="defaultLink"><a href="qtglobal.html">Global Declarations</a></li>
              <li class="defaultLink"><a href="qdeclarativeelements.html">QML elements</a></li>
            </ul> 
          </div>
        </div>
        <div class="box bottombar" id="topics">
          <h2 title="Qt Topics"><span></span>
            Qt Topics</h2>
          <div id="list002" class="list">
            <ul id="ul002" >
               <li class="defaultLink"><a href="qt-basic-concepts.html">Programming with Qt</a></li> 
               <li class="defaultLink"><a href="qtquick.html">Device UIs &amp; Qt Quick</a></li> 
               <li class="defaultLink"><a href="qt-gui-concepts.html">UI Design with Qt</a></li> 
               <li class="defaultLink"><a href="supported-platforms.html">Supported Platforms</a></li>  
               <li class="defaultLink"><a href="technology-apis.html">Qt and Key Technologies</a></li> 
               <li class="defaultLink"><a href="best-practices.html">How-To's and Best Practices</a></li> 
            </ul>  
          </div>
        </div>
        <div class="box" id="examples">
          <h2 title="Examples"><span></span>
            Examples</h2>
          <div id="list003" class="list">
        <ul id="ul003">
              <li class="defaultLink"><a href="all-examples.html">Examples</a></li>
              <li class="defaultLink"><a href="tutorials.html">Tutorials</a></li>
              <li class="defaultLink"><a href="demos.html">Demos</a></li>
              <li class="defaultLink"><a href="qdeclarativeexamples.html">QML Examples</a></li>
            </ul> 
          </div>
        </div>
      </div>
      <div class="wrap">
        <div class="toolbar">
          <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>The Webkit Bridge Tutorial - Hybrid Client Application</li>
            </ul>
          </div>
          <div class="toolbuttons toolblock">
            <ul>
              <li id="smallA" class="t_button">A</li>
              <li id="medA" class="t_button active">A</li>
              <li id="bigA" class="t_button">A</li>
              <li id="print" class="t_button"><a href="javascript:this.print();">
                <span>Print</span></a></li>
            </ul>
        </div>
        </div>
        <div class="content mainContent">
  <link rel="start" href="index.html" />
<p class="naviNextPrevious headerNavi">
</p><p/>
<h1 class="title">The Webkit Bridge Tutorial - Hybrid Client Application</h1>
<span class="subtitle"></span>
<!-- $$$webkit/imageanalyzer-description -->
<div class="descr"> <a name="details"></a>
<p>Files:</p>
<ul>
<li><a href="webkit-imageanalyzer-imageanalyzer-cpp.html">webkit/imageanalyzer/imageanalyzer.cpp</a></li>
<li><a href="webkit-imageanalyzer-imageanalyzer-h.html">webkit/imageanalyzer/imageanalyzer.h</a></li>
<li><a href="webkit-imageanalyzer-mainwindow-cpp.html">webkit/imageanalyzer/mainwindow.cpp</a></li>
<li><a href="webkit-imageanalyzer-mainwindow-h.html">webkit/imageanalyzer/mainwindow.h</a></li>
<li><a href="webkit-imageanalyzer-main-cpp.html">webkit/imageanalyzer/main.cpp</a></li>
<li><a href="webkit-imageanalyzer-imageanalyzer-pro.html">webkit/imageanalyzer/imageanalyzer.pro</a></li>
<li><a href="webkit-imageanalyzer-resources-imageanalyzer-qrc.html">webkit/imageanalyzer/resources/imageanalyzer.qrc</a></li>
</ul>
<p>In this example, we will show how to write a hybrid application using <a href="qtwebkit-bridge.html">QtWebKit Bridge</a>, which distinguishes itself from a thin client in that it performs heavy calculations on the client side in C++, like a native application, but presents nothing more than a <tt>QWebView</tt> for its user interface, displaying web content written in HTML/JavaScript.<p>The application uses <a href="qtconcurrent.html">QtConcurrent</a> to distribute its work across as many CPU cores as are available from the system, so it can process each image in parallel.</p>
<p>For the full reference documentation of <a href="qtwebkit.html">QtWebKit</a> hybrid development, see <a href="qtwebkit-bridge.html">The QtWebKit Bridge</a>.</p>
<p>Initially, you will see a user interface with an empty list of images. Clicking on some of the images in the lower pane below adds them to the list view above, as shown in the screenshot below.</p>
<p class="centerAlign"><img src="images/webkit-imageanalyzer-screenshot.png" alt="" /></p><p>Now, we can click on <b>Analyze</b>, and each image is analyzed using some computationally intensive C++ function, in parallel and on different cores. Progress is shown while the analysis is proceeding.</p>
<p class="centerAlign"><img src="images/webkit-imageanalyzer-progress.png" alt="" /></p><p>and in the end, we will see something like this, where the average RGB values of each image are shown.</p>
<p class="centerAlign"><img src="images/webkit-imageanalyzer-complete.png" alt="" /></p><p>The <a href="designer-to-know.html#mainwindow">MainWindow</a> is defined in C++, and creates a <a href="qnetworkdiskcache.html">QNetworkDiskCache</a> and a <a href="qwebview.html">QWebView</a>, and tells the <a href="qwebview.html">QWebView</a> to load the starting page, providing us with a user interface for the client.</p>
<pre class="cpp"> MainWin<span class="operator">::</span>MainWin(<span class="type"><a href="qwidget.html">QWidget</a></span> <span class="operator">*</span> parent) : <span class="type"><a href="qwebview.html">QWebView</a></span>(parent)
 {
     m_network <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qnetworkaccessmanager.html">QNetworkAccessManager</a></span>(<span class="keyword">this</span>);
     m_cache <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qnetworkdiskcache.html">QNetworkDiskCache</a></span>(<span class="keyword">this</span>);
     m_cache<span class="operator">-</span><span class="operator">&gt;</span>setCacheDirectory(<span class="type"><a href="qdesktopservices.html">QDesktopServices</a></span><span class="operator">::</span>storageLocation(<span class="type"><a href="qdesktopservices.html">QDesktopServices</a></span><span class="operator">::</span>CacheLocation) <span class="operator">+</span> <span class="string">&quot;/imageanalyzer&quot;</span>);
     m_cache<span class="operator">-</span><span class="operator">&gt;</span>setMaximumCacheSize(<span class="number">1000000</span>); <span class="comment">//set the cache to 10megs</span>
     m_network<span class="operator">-</span><span class="operator">&gt;</span>setCache(m_cache);
     page()<span class="operator">-</span><span class="operator">&gt;</span>setNetworkAccessManager(m_network);

     m_analyzer <span class="operator">=</span> <span class="keyword">new</span> ImageAnalyzer(m_cache<span class="operator">,</span> <span class="keyword">this</span>);

     <span class="comment">// Signal is emitted before frame loads any web content:</span>
     <span class="type"><a href="qobject.html">QObject</a></span><span class="operator">::</span>connect(page()<span class="operator">-</span><span class="operator">&gt;</span>mainFrame()<span class="operator">,</span> SIGNAL(javaScriptWindowObjectCleared())<span class="operator">,</span>
                      <span class="keyword">this</span><span class="operator">,</span> SLOT(addJSObject()));

     <span class="comment">// qrc:// URLs refer to resources. See imagenalayzer.qrc</span>
     <span class="type"><a href="qurl.html">QUrl</a></span> startURL <span class="operator">=</span> <span class="type"><a href="qurl.html">QUrl</a></span>(<span class="string">&quot;qrc:/index.html&quot;</span>);

     <span class="comment">// Load web content now!</span>
     setUrl(startURL);
 }</pre>
<p>In this example, the sample content is addressed with the <tt>qrc:/index.html</tt> URL. <tt>qrc:/</tt> indicates that the file is stored as a Qt resource (attached to the executable). In a real-world application, the content and images would likely be retrieved from the network rather than from resources.</p>
<p>We wish to initialize an object reference in the JavaScript web page to point to our <tt>ImageAnalyzer</tt> before any other scripts are run. To do this, we connect the <a href="qwebframe.html#javaScriptWindowObjectCleared">javaScriptWindowObjectCleared()</a> signal to a slot which does the object creation and handoff to JavaScript.</p>
<pre class="cpp"> <span class="type">void</span> MainWin<span class="operator">::</span>addJSObject() {
     <span class="comment">// Add pAnalyzer to JavaScript Frame as member &quot;imageAnalyzer&quot;.</span>
     page()<span class="operator">-</span><span class="operator">&gt;</span>mainFrame()<span class="operator">-</span><span class="operator">&gt;</span>addToJavaScriptWindowObject(<span class="type"><a href="qstring.html">QString</a></span>(<span class="string">&quot;imageAnalyzer&quot;</span>)<span class="operator">,</span> m_analyzer);
 }</pre>
<p>The ImageAnalyzer object is created and added to a JavaScript object on the web page's mainFrame with <tt>addToJavaScriptWindowObject()</tt>.</p>
<p>The start page is resources/index.html. In one of its &lt;div&gt; regions, we have images, each with an <tt>onClick()</tt> handler that calls <tt>addImage()</tt>.</p>
<pre class="cpp"> &lt;div id=imagediv style=&quot;clear:both; text-align:center&quot;&gt;
 &lt;hr/&gt;
     &lt;img src=&quot;images/mtRainier.jpg&quot; height=150px onclick='return addImage(this);' /&gt;
     &lt;img src=&quot;images/bellaCoola.jpg&quot; height=150px onclick='return addImage(this);'/&gt;
     &lt;img src=&quot;images/seaShell.jpg&quot; height=150px onclick='return addImage(this);'/&gt;</pre>
<p>Clicking an image adds it to an images list.</p>
<pre class="cpp"> function addImage(newimg) {
     var imglist = document.getElementById('imglist');
     var curChildren = imglist.childNodes;
     var newline = document.createElement('option');
     newline.innerHTML = newimg.src.substring(newimg.src.lastIndexOf('/')+1);
     newline.value = newimg.src;
     imglist.appendChild(newline);
 }</pre>
<p>The <b>Analyze</b> button at the bottom of the image list is clicked when we want to start the analysis:</p>
<pre class="cpp">     &lt;div style=&quot;float:right; width:50%; border-left: solid 1px black&quot;&gt;
         &lt;div id=&quot;listdiv&quot; align=&quot;center&quot;&gt;
             &lt;h5&gt;Images to be analyzed:&lt;/h5&gt;
             &lt;select multiple size=10 id=imglist style=&quot;width:80%&quot;&gt;&lt;/select&gt;
             &lt;br /&gt;
             &lt;input type=&quot;button&quot; id=&quot;evalbutton&quot; value=&quot;Analyze&quot; onclick=&quot;analyzeImages()&quot; /&gt;
         &lt;/div&gt;
     &lt;/div&gt;</pre>
<p>When the user clicks the <b>Analyze</b> button, <tt>analyzeImages()</tt> is called, another regular JavaScript method, shown below. Notice it assumes the <tt>imageAnalyzer</tt> object is already defined and initialized in JavaScript space, but we guaranteed that by connecting our setup slot to the appropriate signal, <a href="qwebframe.html#javaScriptWindowObjectCleared">javaScriptWindowObjectCleared()</a>.</p>
<pre class="cpp"> function analyzeImages() {
     connectSlots();
     var imglist = document.getElementsByTagName('option');
     if (imglist.length &gt; 0) {
         stringlist = [];
         for(var i=0; i&lt;imglist.length; i++) {
             stringlist[i]=imglist[i].value;
         }
         if (!imageAnalyzer.busy) {
             remaining = stringlist.length;
             imageAnalyzer.startAnalysis(stringlist);
         } else {
             alert(&quot;Processing, please wait until finished.&quot;);
         }</pre>
<p>The only methods on <tt>ImageAnalyzer</tt> that we can or do call from JavaScript are those which are exposed through {The Meta-Object System}{Qt's MetaObject} system: <a href="properties.html">property</a> getter/setter methods, <tt>public</tt> <a href="signalsandslots.html">signals and slots</a>, and other <a href="qobject.html#Q_INVOKABLE">Q_INVOKABLE</a> functions.</p>
<pre class="cpp"> <span class="keyword">class</span> ImageAnalyzer : <span class="keyword">public</span> <span class="type"><a href="qobject.html">QObject</a></span>
 {
     Q_OBJECT
 <span class="keyword">public</span>:
     ImageAnalyzer(<span class="type"><a href="qnetworkdiskcache.html">QNetworkDiskCache</a></span> <span class="operator">*</span> netcache<span class="operator">,</span> <span class="type"><a href="qobject.html">QObject</a></span> <span class="operator">*</span> parent<span class="operator">=</span><span class="number">0</span>);

     <span class="type"><a href="qcolor.html#QRgb-typedef">QRgb</a></span> lastResults();
     <span class="type">float</span> lastRed();
     <span class="type">float</span> lastGreen();
     <span class="type">float</span> lastBlue();
     <span class="type">bool</span> isBusy();
     Q_PROPERTY(<span class="type">bool</span> busy READ isBusy);
     Q_PROPERTY(<span class="type">float</span> red READ lastRed);
     Q_PROPERTY(<span class="type">float</span> green READ lastGreen);
     Q_PROPERTY(<span class="type">float</span> blue READ lastBlue);
     <span class="operator">~</span>ImageAnalyzer();

 <span class="keyword">public</span> <span class="keyword">slots</span>:
     <span class="comment">/*! initiates analysis of all the urls in the list */</span>
     <span class="type">void</span> startAnalysis(<span class="keyword">const</span> <span class="type"><a href="qstringlist.html">QStringList</a></span> <span class="operator">&amp;</span> urls);

 <span class="keyword">signals</span>:
     <span class="type">void</span> finishedAnalysis();
     <span class="type">void</span> updateProgress(<span class="type">int</span> completed<span class="operator">,</span> <span class="type">int</span> total);
     ...
 <span class="keyword">private</span>:
 <span class="type"><a href="qnetworkaccessmanager.html">QNetworkAccessManager</a></span><span class="operator">*</span> m_network;
 <span class="type"><a href="qnetworkdiskcache.html">QNetworkDiskCache</a></span><span class="operator">*</span> m_cache;
 <span class="type"><a href="qstringlist.html">QStringList</a></span> m_URLQueue;
 <span class="type"><a href="qlist.html">QList</a></span><span class="operator">&lt;</span><span class="type"><a href="qimage.html">QImage</a></span><span class="operator">&gt;</span> m_imageQueue;
 <span class="type">int</span> m_outstandingFetches;
 <span class="type"><a href="qfuturewatcher.html">QFutureWatcher</a></span><span class="operator">&lt;</span><span class="type"><a href="qcolor.html#QRgb-typedef">QRgb</a></span><span class="operator">&gt;</span> <span class="operator">*</span> m_watcher;</pre>
<p>Most of the members are set up in the constructor:</p>
<pre class="cpp"> ImageAnalyzer<span class="operator">::</span>ImageAnalyzer(<span class="type"><a href="qnetworkdiskcache.html">QNetworkDiskCache</a></span><span class="operator">*</span> netcache<span class="operator">,</span> <span class="type"><a href="qobject.html">QObject</a></span><span class="operator">*</span> parent)
     : <span class="type"><a href="qobject.html">QObject</a></span>(parent)<span class="operator">,</span> m_cache(netcache)<span class="operator">,</span> m_outstandingFetches(<span class="number">0</span>)
 {
     <span class="comment">/*  ImageAnalyzer only wants to receive http responses
         for requests that it makes, so that's why it has its own
         QNetworkAccessManager. */</span>
     m_network <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qnetworkaccessmanager.html">QNetworkAccessManager</a></span>(<span class="keyword">this</span>);
     m_watcher <span class="operator">=</span> <span class="keyword">new</span> <span class="type"><a href="qfuturewatcher.html">QFutureWatcher</a></span><span class="operator">&lt;</span><span class="type"><a href="qcolor.html#QRgb-typedef">QRgb</a></span><span class="operator">&gt;</span>(<span class="keyword">this</span>);
     <span class="comment">/*  We want to share a cache with the web browser,
         in case it has some images we want: */</span>
     m_network<span class="operator">-</span><span class="operator">&gt;</span>setCache(m_cache);

     <span class="type"><a href="qobject.html">QObject</a></span><span class="operator">::</span>connect(m_network<span class="operator">,</span> SIGNAL(finished(<span class="type"><a href="qnetworkreply.html">QNetworkReply</a></span><span class="operator">*</span>))<span class="operator">,</span>
                      <span class="keyword">this</span><span class="operator">,</span> SLOT(handleReply(<span class="type"><a href="qnetworkreply.html">QNetworkReply</a></span><span class="operator">*</span>)));
     <span class="type"><a href="qobject.html">QObject</a></span><span class="operator">::</span>connect(m_watcher<span class="operator">,</span> SIGNAL(finished())<span class="operator">,</span>
                      <span class="keyword">this</span><span class="operator">,</span> SLOT(doneProcessing()));
     <span class="type"><a href="qobject.html">QObject</a></span><span class="operator">::</span>connect(m_watcher<span class="operator">,</span> SIGNAL(progressValueChanged(<span class="type">int</span>))<span class="operator">,</span>
                      <span class="keyword">this</span><span class="operator">,</span> SLOT(progressStatus(<span class="type">int</span>)));
 }</pre>
<p>Back on the JavaScript side, we want to connect signals from this object to JavaScript functions on our web page, after the web page is loaded, but before the images are analyzed.</p>
<p>From <tt>connectSlots()</tt>, we can see how to connect signals from the imageAnalyzer object to regular JavaScript functions, which can also behave like slots. We use this to monitor and display progress from the C++ side.</p>
<pre class="cpp"> function connectSlots()
 {
     if ( !connected ) {
         connected = true;
         imageAnalyzer.finishedAnalysis.connect(this, finished);
         imageAnalyzer.updateProgress.connect(this, updateProg);
     }
 }</pre>
<p>The only public slot is <tt>startAnalysis()</tt>, called to place a list of URLs into the image analyzer's <a href="qtconcurrent.html">QtConcurrent</a> processing queue from JavaScript space.</p>
<pre class="cpp"> <span class="type">void</span> ImageAnalyzer<span class="operator">::</span>startAnalysis(<span class="keyword">const</span> <span class="type"><a href="qstringlist.html">QStringList</a></span> <span class="operator">&amp;</span> urls)
 {
     m_URLQueue <span class="operator">=</span> urls;
     fetchURLs();
 }</pre>
<p>The images need to be loaded again now, which is why fetchURLs first checks the cache to see if we can save an extra network get.</p>
<pre class="cpp"> <span class="type">void</span> ImageAnalyzer<span class="operator">::</span>fetchURLs()
 {
     <span class="keyword">while</span> (<span class="operator">!</span>m_URLQueue<span class="operator">.</span>isEmpty())
     {
         <span class="type"><a href="qstring.html">QString</a></span> url <span class="operator">=</span> m_URLQueue<span class="operator">.</span>takeFirst();
         <span class="type"><a href="qurl.html">QUrl</a></span> URL <span class="operator">=</span> <span class="type"><a href="qurl.html">QUrl</a></span>(url);
         <span class="type"><a href="qiodevice.html">QIODevice</a></span> <span class="operator">*</span> pData <span class="operator">=</span> m_cache<span class="operator">-</span><span class="operator">&gt;</span>data(URL);
         <span class="comment">// Is image already loaded in cache?</span>
         <span class="keyword">if</span> (pData <span class="operator">=</span><span class="operator">=</span> <span class="number">0</span>) {
             <span class="comment">// HTTP Get image over network.</span>
             m_outstandingFetches<span class="operator">+</span><span class="operator">+</span>;
             <span class="type"><a href="qnetworkrequest.html">QNetworkRequest</a></span> request <span class="operator">=</span> <span class="type"><a href="qnetworkrequest.html">QNetworkRequest</a></span>(URL);
             request<span class="operator">.</span>setRawHeader(<span class="string">&quot;User-Agent&quot;</span><span class="operator">,</span> <span class="string">&quot;Nokia - Custom QT app&quot;</span>);
             m_network<span class="operator">-</span><span class="operator">&gt;</span>get(request);
         } <span class="keyword">else</span> {
             <span class="comment">// Get image from cache</span>
             <span class="type"><a href="qimage.html">QImage</a></span> image;
             image<span class="operator">.</span>load(pData<span class="operator">,</span> <span class="number">0</span>);
             <span class="keyword">if</span> (<span class="operator">!</span>image<span class="operator">.</span>isNull())
                 queueImage(image);
             <span class="keyword">delete</span>(pData);
         }
     }
 }</pre>
<p>For the images that were not in the cache, <tt>handleReply()</tt> will load them into a <a href="qimage.html">QImage</a> when the data is ready.</p>
<pre class="cpp"> <span class="type">void</span> ImageAnalyzer<span class="operator">::</span>handleReply(<span class="type"><a href="qnetworkreply.html">QNetworkReply</a></span> <span class="operator">*</span> pReply)
 {
     m_outstandingFetches<span class="operator">-</span><span class="operator">-</span>;
     <span class="keyword">if</span> (pReply<span class="operator">-</span><span class="operator">&gt;</span>error()) {
         <a href="qtglobal.html#qDebug">qDebug</a>() <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="string">&quot;Error code&quot;</span> <span class="operator">&lt;</span><span class="operator">&lt;</span> pReply<span class="operator">-</span><span class="operator">&gt;</span>error();
         <a href="qtglobal.html#qDebug">qDebug</a>() <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="string">&quot;Http code&quot;</span> <span class="operator">&lt;</span><span class="operator">&lt;</span> pReply<span class="operator">-</span><span class="operator">&gt;</span>attribute(<span class="type"><a href="qnetworkrequest.html">QNetworkRequest</a></span><span class="operator">::</span>HttpStatusCodeAttribute);
         <span class="keyword">return</span>;
     }
     <span class="type"><a href="qimage.html">QImage</a></span> image;
     image<span class="operator">.</span>load(pReply<span class="operator">,</span> <span class="number">0</span>);
     pReply<span class="operator">-</span><span class="operator">&gt;</span>deleteLater();
     <span class="keyword">if</span> (image<span class="operator">.</span>isNull()) {
         <a href="qtglobal.html#qDebug">qDebug</a>() <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="string">&quot;bad image&quot;</span>;
         <a href="qtglobal.html#qDebug">qDebug</a>() <span class="operator">&lt;</span><span class="operator">&lt;</span> pReply<span class="operator">-</span><span class="operator">&gt;</span>rawHeaderList();
         foreach(<span class="type"><a href="qbytearray.html">QByteArray</a></span> element<span class="operator">,</span> pReply<span class="operator">-</span><span class="operator">&gt;</span>rawHeaderList()) {
             <a href="qtglobal.html#qDebug">qDebug</a>() <span class="operator">&lt;</span><span class="operator">&lt;</span> element <span class="operator">&lt;</span><span class="operator">&lt;</span> <span class="string">&quot; = &quot;</span> <span class="operator">&lt;</span><span class="operator">&lt;</span> pReply<span class="operator">-</span><span class="operator">&gt;</span>rawHeader(element);
         }
         <span class="keyword">return</span>;
     }
     queueImage(image);
 }</pre>
<p>After the images are loaded, they are queued up in preparation to be sent in a batch for analysis to a <a href="qfuturewatcher.html">QFutureWatcher</a>, which will distribute the processing across multiple threads and cores, depending on how many are available.</p>
<pre class="cpp"> <span class="type">void</span> ImageAnalyzer<span class="operator">::</span>queueImage(<span class="type"><a href="qimage.html">QImage</a></span> img)
 {
     <span class="keyword">if</span> (<span class="operator">!</span>img<span class="operator">.</span>isNull())
         m_imageQueue <span class="operator">&lt;</span><span class="operator">&lt;</span> img;

     <span class="keyword">if</span> (m_outstandingFetches <span class="operator">=</span><span class="operator">=</span> <span class="number">0</span> <span class="operator">&amp;</span><span class="operator">&amp;</span> m_URLQueue<span class="operator">.</span>isEmpty()) {
         m_watcher<span class="operator">-</span><span class="operator">&gt;</span>setFuture(<span class="type"><a href="qtconcurrent.html">QtConcurrent</a></span><span class="operator">::</span>mapped(m_imageQueue<span class="operator">,</span> averageRGB));
     }
 }</pre>
<p>The function that gets performed on each image is <tt>averageRGB()</tt>, as specified in argument 2 to the <a href="qtconcurrentmap.html#mapped">QtConcurrent::mapped</a>() function. Notice it repeats the same calculations 100 times on each pixel to keep the CPU very busy. This is done only for the purposes of the demo so that the analysis takes a noticeable time to complete.</p>
<pre class="cpp"> <span class="type"><a href="qcolor.html#QRgb-typedef">QRgb</a></span> averageRGB(<span class="keyword">const</span> <span class="type"><a href="qimage.html">QImage</a></span> <span class="operator">&amp;</span>img)
 {
     <span class="type">int</span> pixelCount <span class="operator">=</span> img<span class="operator">.</span>width() <span class="operator">*</span> img<span class="operator">.</span>height();
     <span class="type">int</span> rAvg<span class="operator">,</span> gAvg<span class="operator">,</span> bAvg;

     <span class="comment">// We waste some time here:</span>
     <span class="keyword">for</span> (<span class="type">int</span> timeWaster<span class="operator">=</span><span class="number">0</span>; timeWaster <span class="operator">&lt;</span> <span class="number">100</span>; timeWaster<span class="operator">+</span><span class="operator">+</span>) {
         <span class="type"><a href="qtglobal.html#quint64-typedef">quint64</a></span> rTot <span class="operator">=</span> <span class="number">0</span>;
         <span class="type"><a href="qtglobal.html#quint64-typedef">quint64</a></span> gTot <span class="operator">=</span> <span class="number">0</span>;
         <span class="type"><a href="qtglobal.html#quint64-typedef">quint64</a></span> bTot <span class="operator">=</span> <span class="number">0</span>;
         <span class="keyword">for</span> (<span class="type">int</span> i<span class="operator">=</span><span class="number">0</span>; i <span class="operator">&lt;</span> img<span class="operator">.</span>width(); i<span class="operator">+</span><span class="operator">+</span>) {
             <span class="keyword">for</span> (<span class="type">int</span> j<span class="operator">=</span><span class="number">0</span>; j <span class="operator">&lt;</span> img<span class="operator">.</span>height(); j<span class="operator">+</span><span class="operator">+</span>) {
                 <span class="type"><a href="qcolor.html#QRgb-typedef">QRgb</a></span> pixel <span class="operator">=</span> img<span class="operator">.</span>pixel(i<span class="operator">,</span>j);
                 rTot <span class="operator">+</span><span class="operator">=</span> <a href="qcolor.html#qRed">qRed</a>(pixel);
                 gTot <span class="operator">+</span><span class="operator">=</span> <a href="qcolor.html#qGreen">qGreen</a>(pixel);
                 bTot <span class="operator">+</span><span class="operator">=</span> <a href="qcolor.html#qBlue">qBlue</a>(pixel);
             }
         }
         rAvg <span class="operator">=</span> (rTot)<span class="operator">/</span>(pixelCount);
         gAvg <span class="operator">=</span> (gTot)<span class="operator">/</span>(pixelCount);
         bAvg <span class="operator">=</span> (bTot)<span class="operator">/</span>(pixelCount);
     }
     <span class="keyword">return</span> <a href="qcolor.html#qRgb">qRgb</a>(rAvg<span class="operator">,</span> gAvg<span class="operator">,</span> bAvg);
 }</pre>
</div>
<!-- @@@webkit/imageanalyzer -->
<p class="naviNextPrevious footerNavi">
</p>
      </div>
    </div>
    </div> 
    <div class="ft">
      <span></span>
    </div>
  </div> 
  <div class="footer">
    <p>
      <acronym title="Copyright">&copy;</acronym> 2015 The Qt Company Ltd.
      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>
      Qt and respective logos are trademarks of The Qt Company Ltd 
      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>

  <script src="scripts/functions.js" type="text/javascript"></script>
</body>
</html>