Update copyright headers
[qt:qt.git] / doc / src / examples / webkit-bridge-imageanalyzer.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2015 The Qt Company Ltd.
4 ** Contact: http://www.qt.io/licensing/
5 **
6 ** This file is part of the documentation of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:FDL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and The Qt Company. For licensing terms
14 ** and conditions see http://www.qt.io/terms-conditions. For further
15 ** information use the contact form at http://www.qt.io/contact-us.
16 **
17 ** GNU Free Documentation License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Free
19 ** Documentation License version 1.3 as published by the Free Software
20 ** Foundation and appearing in the file included in the packaging of
21 ** this file.  Please review the following information to ensure
22 ** the GNU Free Documentation License version 1.3 requirements
23 ** will be met: http://www.gnu.org/copyleft/fdl.html.
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27
28 /*!
29     \example webkit/imageanalyzer
30     \startpage {index.html}{Qt Reference Documentation}
31     \title The Webkit Bridge Tutorial - Hybrid Client Application
32
33     \brief In this example, we will show how to write a hybrid application using
34 \l{The QtWebKit Bridge}{QtWebKit Bridge}, which distinguishes itself from a
35 thin client in that it performs heavy calculations on the client side in C++,
36 like a native application, but presents nothing more than a \c QWebView for its
37 user interface, displaying web content written in HTML/JavaScript.
38
39 The application uses QtConcurrent to distribute its work across as many CPU cores as
40 are available from the system, so it can process each image in parallel.
41
42 For the full reference documentation of QtWebKit hybrid development, see 
43 \l{qtwebkit-bridge.html}{The QtWebKit Bridge}.
44
45 Initially, you will see a user interface with an empty list of images. Clicking
46 on some of the images in the lower pane below adds them to the list view above,
47 as shown in the screenshot below.
48
49     \image webkit-imageanalyzer-screenshot.png
50
51 Now, we can click on \bold Analyze, and each image is analyzed using some
52 computationally intensive C++ function, in parallel and on different cores.
53 Progress is shown while the analysis is proceeding.
54
55     \image webkit-imageanalyzer-progress.png
56
57 and in the end, we will see something like this, where the average RGB values of
58 each image are shown.
59
60     \image webkit-imageanalyzer-complete.png
61
62 The MainWindow is defined in C++, and creates a \l QNetworkDiskCache and a
63 \l QWebView, and tells the \l QWebView to load the starting page, providing us
64 with a user interface for the client.
65
66   \snippet examples/webkit/imageanalyzer/mainwindow.cpp MainWindow - constructor
67
68 In this example, the sample content is addressed with the \tt qrc:/index.html
69 URL. \tt qrc:/ indicates that the file is stored as a Qt resource (attached to
70 the executable). In a real-world application, the content and images would
71 likely be retrieved from the network rather than from resources.
72
73 We wish to initialize an object reference in the JavaScript web page to point
74 to our \tt ImageAnalyzer before any other scripts are run. To do this, we
75 connect the \l{QWebFrame::}{javaScriptWindowObjectCleared()} signal to a slot
76 which does the object creation and handoff to JavaScript.
77
78   \snippet examples/webkit/imageanalyzer/mainwindow.cpp MainWindow - addJSObject
79
80 The ImageAnalyzer object is created and added to a JavaScript object on the web
81 page's mainFrame with \c addToJavaScriptWindowObject().
82
83     The start page is resources/index.html.
84     In one of its <div> regions, we have images, each
85     with an \c onClick() handler that calls \c addImage().
86
87     \snippet examples/webkit/imageanalyzer/resources/index.html sample images
88
89 Clicking an image adds it to an images list.
90
91     \snippet examples/webkit/imageanalyzer/resources/index.html addImage
92
93 The \bold {Analyze} button at the bottom of the image list is clicked when we
94 want to start the analysis:
95
96     \snippet examples/webkit/imageanalyzer/resources/index.html images list
97
98 When the user clicks the \bold {Analyze} button, \c analyzeImages() is called,
99 another regular JavaScript method, shown below.
100 Notice it assumes the \c imageAnalyzer object is already defined and initialized
101 in JavaScript space, but we guaranteed that by connecting our setup slot to the
102 appropriate signal, \l{QWebFrame::}{javaScriptWindowObjectCleared()}.
103
104     \snippet examples/webkit/imageanalyzer/resources/index.html analyzeImages
105
106 The only methods on \c ImageAnalyzer that we can or do call from JavaScript are
107 those which are exposed through \{The Meta-Object System}{Qt's MetaObject}
108 system: \l{The Property System}{property} getter/setter methods,
109 \c public \l {Signals & Slots}{signals and slots}, and other 
110 \l{Q_INVOKABLE}{Q_INVOKABLE} functions.
111
112 \snippet examples/webkit/imageanalyzer/imageanalyzer.h ImageAnalyzer - public interface
113 \dots
114 \snippet examples/webkit/imageanalyzer/imageanalyzer.h ImageAnalyzer - private members
115
116 Most of the members are set up in the constructor:
117
118 \snippet examples/webkit/imageanalyzer/imageanalyzer.cpp ImageAnalyzer - Constructor
119
120 Back on the JavaScript side, we want to connect signals from this object to
121 JavaScript functions on our web page, after the web page is loaded, but before
122 the images are analyzed.
123
124 From \c connectSlots(), we can see how to connect signals from the imageAnalyzer
125 object to regular JavaScript functions, which can also behave like slots. We use
126 this to monitor and display progress from the C++ side.
127
128     \snippet examples/webkit/imageanalyzer/resources/index.html connect slots
129
130 The only public slot is \c startAnalysis(), called to place
131 a list of URLs into the image analyzer's QtConcurrent processing queue
132 from JavaScript space.
133
134 \snippet examples/webkit/imageanalyzer/imageanalyzer.cpp ImageAnalyzer - startAnalysis
135
136 The images need to be loaded again now, which is why fetchURLs first checks the
137 cache to see if we can save an extra network get.
138
139 \snippet examples/webkit/imageanalyzer/imageanalyzer.cpp ImageAnalyzer - fetchURLs
140
141 For the images that were not in the cache, \c handleReply()
142 will load them into a QImage when the data is ready.
143
144 \snippet examples/webkit/imageanalyzer/imageanalyzer.cpp ImageAnalyzer - handleReply
145
146 After the images are loaded, they are queued up in preparation to be
147 sent in a batch for analysis to a \l QFutureWatcher, which will distribute the
148 processing across multiple threads and cores, depending on how many are available.
149
150 \snippet examples/webkit/imageanalyzer/imageanalyzer.cpp ImageAnalyzer - queueImage
151
152 The function that gets performed on each image is \c averageRGB(),
153 as specified in argument 2 to the \l{QtConcurrent::mapped()} function.
154 Notice it repeats the same calculations 100 times on each pixel to keep the CPU
155 very busy. This is done only for the purposes of the demo so that the analysis
156 takes a noticeable time to complete.
157
158 \snippet examples/webkit/imageanalyzer/imageanalyzer.cpp ImageAnalyzer - averageRGB
159
160 */
161