/usr/share/qt5/doc/qtwebkit/qtwebkit-goes-mobile.html is in qtwebkit5-doc-html 5.212.0~alpha2-7ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 | <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<!-- qtwebkit-goes-mobile.qdoc -->
<title>Qt WebKit Goes Mobile | Qt 5.212.0</title>
<link rel="stylesheet" type="text/css" href="style/offline-simple.css" />
<script type="text/javascript">
document.getElementsByTagName("link").item(0).setAttribute("href", "style/offline.css");
// loading style sheet breaks anchors that were jumped to before
// so force jumping to anchor again
setTimeout(function() {
var anchor = location.hash;
// need to jump to different anchor first (e.g. none)
location.hash = "#";
setTimeout(function() {
location.hash = anchor;
}, 0);
}, 0);
</script>
</head>
<body>
<div class="header" id="qtdocheader">
<div class="main">
<div class="main-rounded">
<div class="navigationbar">
<table><tr>
<td >Qt 5.212.0</td><td >Qt WebKit Goes Mobile</td></tr></table><table class="buildversion"><tr>
<td id="buildversion" width="100%" align="right">Qt 5.212.0 Reference Documentation</td>
</tr></table>
</div>
</div>
<div class="content">
<div class="line">
<div class="content mainContent">
<p class="naviNextPrevious headerNavi">
</p><p/>
<div class="sidebar">
<div class="toc">
<h3><a name="toc">Contents</a></h3>
<ul>
<li class="level1"><a href="#overview">Overview</a></li>
<li class="level1"><a href="#resize-to-contents">Resize to Contents</a></li>
<li class="level1"><a href="#using-a-view-as-the-window-onto-the-contents">Using a View as the Window onto the Contents</a></li>
<li class="level1"><a href="#adjusting-how-contents-are-laid-out">Adjusting How Contents are Laid Out</a></li>
<li class="level1"><a href="#the-viewport-meta-tag">The 'viewport' Meta-Tag</a></li>
<li class="level1"><a href="#enabling-the-tiling">Enabling the Tiling</a></li>
<li class="level1"><a href="#avoiding-scrollable-subelements">Avoiding Scrollable Subelements</a></li>
</ul>
</div>
<div class="sidebar-content" id="sidebar-content"></div></div>
<h1 class="title">Qt WebKit Goes Mobile</h1>
<span class="subtitle"></span>
<!-- $$$qtwebkit-goes-mobile.html-description -->
<div class="descr"> <a name="details"></a>
<a name="overview"></a>
<h2 id="overview">Overview</h2>
<p>A lot of effort has been put into Qt WebKit to make it attractive for use on mobile devices.</p>
<p>The goal of this tutorial is to help you understand the mobile features and how to make the best of them, in other words, how to create a good mobile web view that can be used on touch devices.</p>
<p>If you want to target mobile devices you should consider using <a href="qgraphicswebview.html">QGraphicsWebView</a> instead of <a href="qwebview.html">QWebView</a>. Since <a href="qwebview.html">QWebView</a> is based on the <a href="../qtwidgets/qwidget.html">QWidget</a> system, it cannot easily support rotation, overlays, hardware accelerated compositing and tiling. If you need a <a href="../qtwidgets/qwidget.html">QWidget</a> anyway, you can always construct a <a href="../qtwidgets/qgraphicsview.html">QGraphicsView</a> (which is a <a href="../qtwidgets/qwidget.html">QWidget</a>) with a <a href="qgraphicswebview.html">QGraphicsWebView</a> inside.</p>
<p>So let's start with a very simple <a href="qgraphicswebview.html">QGraphicsWebView</a> based "browser":</p>
<pre class="cpp">
<span class="type">int</span> main(<span class="type">int</span> argc<span class="operator">,</span> <span class="type">char</span> <span class="operator">*</span><span class="operator">*</span>argv)
{
<span class="type"><a href="../qtwidgets/qapplication.html">QApplication</a></span> app(argc<span class="operator">,</span> argv);
<span class="keyword">const</span> <span class="type">int</span> width <span class="operator">=</span> <span class="number">640</span>;
<span class="keyword">const</span> <span class="type">int</span> height <span class="operator">=</span> <span class="number">480</span>;
<span class="type"><a href="../qtwidgets/qgraphicsscene.html">QGraphicsScene</a></span> scene;
<span class="type"><a href="../qtwidgets/qgraphicsview.html">QGraphicsView</a></span> view(<span class="operator">&</span>scene);
view<span class="operator">.</span>setFrameShape(<span class="type"><a href="../qtwidgets/qframe.html">QFrame</a></span><span class="operator">::</span>NoFrame);
view<span class="operator">.</span>setVerticalScrollBarPolicy(<span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>ScrollBarAlwaysOff);
view<span class="operator">.</span>setHorizontalScrollBarPolicy(<span class="type"><a href="../qtcore/qt.html">Qt</a></span><span class="operator">::</span>ScrollBarAlwaysOff);
<span class="type"><a href="qgraphicswebview.html">QGraphicsWebView</a></span> webview;
webview<span class="operator">.</span>resize(width<span class="operator">,</span> height);
webview<span class="operator">.</span>load(<span class="type"><a href="../qtcore/qurl.html">QUrl</a></span>(<span class="string">"http://doc.qt.nokia.com/"</span>));
scene<span class="operator">.</span>addItem(<span class="operator">&</span>webview);
view<span class="operator">.</span>resize(width<span class="operator">,</span> height);
view<span class="operator">.</span>show();
<span class="keyword">return</span> app<span class="operator">.</span>exec();
}
</pre>
<p>Here we set up a <a href="../qtwidgets/qgraphicsview.html">QGraphicsView</a> application and add a <a href="qgraphicswebview.html">QGraphicsWebView</a> to the scene. Notice that we're disabling the scrollbars on the <a href="../qtwidgets/qgraphicsview.html">QGraphicsView</a> because Qt WebKit handles scrolling and scrollbars automatically. This is to allow scrolling optimizations and to enable web authors to interact with the scrollbars, for instance, to style them differently.</p>
<p>On touch-based mobile devices a feature known as tiling is often used. It is used due to the interaction model (touch) as well as a scrolling optimization. With this optimization we will have to deal with scrolling ourselves, and we will have to disable features like scroll bar styling. This is not usually a problem, since mobile browsers do not usually show scroll bars, but use scroll indicators instead.</p>
<p>Tiling basically means that the contents of the viewport is separated into a grid of tiles, so that when you update an area, instead of just updating the area, you actually update the whole tile or sub-regions of it. This offers a few advantages for scrolling as, when you scroll, you do not need to repaint the new visible area for each scroll step, but you simply update a row of tiles each time; these tiles are often only partly on the screen. This minimizes all the painting calls that we have to do and enables kinetic scrolling.</p>
<p>Loading, rendering, and laying out are blocking operations. Though barely noticeable on desktop machines, these operations can block for a long time on a mobile device, letting the user believe the application has become unresponsive. Additionally, scrolling will also stall when the user uses his fingers to scroll, leading to a bad user experience.</p>
<p>One way to overcome this issue, is to do all loading, laying out and painting (basically all non-UI related work) in another thread or process, and just blit the result from the web process/thread to the UI. There is research in progress to enable this for a future version of Qt WebKit, using WebKit2, but for now, freezing the backing store can help when performing a zooming operation, for instance. This will be discussed later, in the <a href="qtwebkit-goes-mobile.html#enabling-the-tiling">Enabling the Tiling</a> section.</p>
<p>When using tiles, you can blit any tile available when scrolling. When no tile is available you can show a checkerboard tile instead, not letting the scrolling wait for the tiles to be updated. This results in a responsive interface, with the only disadvantage that you might see checkerboard tiles from time to time.</p>
<p>The use of tiles also helps with zooming. Repainting at each zoom level change during a zoom animation is basically impossible on a mobile device (or desktop for that matter) and thus, with tiling, you can stop the tiles from being updated and just scale the existing tiles. Then, at the end of the animation, update tiles on top of the scaled ones. For now we will ignore the blocking issue and concentrate on the tiling and the interaction model. More information about Tiling can be found here: <a href="http://doc.qt.nokia.com/4.7/qwebsettings.html#WebAttribute-enum">http://doc.qt.nokia.com/4.7/qwebsettings.html#WebAttribute-enum</a> (see the entry for TiledBackingStoreEnabled).</p>
<a name="resize-to-contents"></a>
<h2 id="resize-to-contents">Resize to Contents</h2>
<p>When using tiling, we want the <a href="qgraphicswebview.html">QGraphicsWebView</a> to act as our content, as it supports tiling. In order for this we need to make it resize itself to the size of its contents. For this we will use <a href="qgraphicswebview.html#resizesToContents-prop">QGraphicsWebView::resizesToContents</a>.</p>
<p>This setting removes the scroll bars for us on the main frame and makes our <a href="qgraphicswebview.html">QGraphicsWebView</a> resize itself to the size of its content.</p>
<p>Enabling it is as easy as setting the property:</p>
<pre class="cpp">
webview<span class="operator">.</span>setResizesToContents(<span class="keyword">true</span>);
</pre>
<p>The property should be used in conjunction with the <a href="qwebpage.html#preferredContentsSize-prop">QWebPage::preferredContentsSize</a> property. If not explicitly set, it is automatically set to a reasonable value.</p>
<p>If we expand our mobile web view to the size of the contents of its contained page, the view will be bigger than the device screen.</p>
<a name="using-a-view-as-the-window-onto-the-contents"></a>
<h2 id="using-a-view-as-the-window-onto-the-contents">Using a View as the Window onto the Contents</h2>
<p>The idea is to have a custom widget which has a <a href="qgraphicswebview.html">QGraphicsWebView</a> as a class member. Remember that the <a href="qgraphicswebview.html">QGraphicsWebView</a> will be as big as its content's size, so this custom widget will serve as a viewport onto the web view.</p>
<p>The following code snippet illustrates this:</p>
<pre class="cpp">
<span class="keyword">class</span> MobileWebView : <span class="keyword">public</span> <span class="type"><a href="../qtwidgets/qgraphicswidget.html">QGraphicsWidget</a></span> {
Q_OBJECT
<span class="keyword">public</span>:
MobileWebView(<span class="type"><a href="../qtwidgets/qgraphicsitem.html">QGraphicsItem</a></span> <span class="operator">*</span>parent <span class="operator">=</span> <span class="number">0</span>);
<span class="operator">~</span>MobileWebView();
bool mousePress(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qpoint.html">QPoint</a></span> <span class="operator">&</span>value);
<span class="type">void</span> mouseMove(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qpoint.html">QPoint</a></span> <span class="operator">&</span>value);
<span class="type">void</span> mouseRelease(<span class="keyword">const</span> <span class="type"><a href="../qtcore/qpoint.html">QPoint</a></span> <span class="operator">&</span>value);
<span class="keyword">private</span>:
<span class="type"><a href="qgraphicswebview.html">QGraphicsWebView</a></span><span class="operator">*</span> webView;
};
</pre>
<p>In order to properly handle mouse events, you must install an event filter on the web view or stack it behind its parent object (<a href="../qtwidgets/qgraphicsitem.html#GraphicsItemFlag-enum">QGraphicsItem::ItemStacksBehindParent</a>). By doing this the mouse events will reach a <code>MobileWebView</code> instance before they reach the member <a href="qgraphicswebview.html">QGraphicsWebView</a>. Keep in mind that you'll need to add some logic in order to distinguish between different mouse events and gestures, such as a single click, double click and click-and-pan. Besides, scrolling and zooming will have to be implemented manually.</p>
<a name="adjusting-how-contents-are-laid-out"></a>
<h2 id="adjusting-how-contents-are-laid-out">Adjusting How Contents are Laid Out</h2>
<p>When testing the above on a device, you will notice that many pages are not laid out very nicely. In particular, the width of the content may be larger than the width of the device. This is due to the way web contents are laid out. First, the viewport width is used for fitting the contents. If the contents do not fit due to a non-flexible element with a width larger than the viewport width, the minimum possible width will be used. As most pages are written with a desktop browser in mind, that makes only very few sites fit into the width of a mobile device.</p>
<p>Qt WebKit has a way to force a layout to a given width or height. What really matters here is the width. If you lay out a page to a given width, it will get that width and images might be cropped. The width or height is also used for laying out fixed elements, but when we resize the <a href="qgraphicswebview.html">QGraphicsWebView</a> to the size of the contents, fixed elements will not be relative to the view, which is the behavior found on most mobile browsers.</p>
<p>We saw that the <a href="qwebpage.html#preferredContentsSize-prop">QWebPage::preferredContentsSize</a> property is automatically set to a reasonable value when using <a href="qgraphicswebview.html#resizesToContents-prop">QGraphicsWebView::resizesToContents</a>.</p>
<p>As you can imagine, laying out with a smaller viewport can cause pages to break, therefore a default value has been chosen so that it almost breaks no pages while still making pages fit. This value is 960x800. If the device has a greater resolution, this value can be changed like this:</p>
<pre class="cpp">
webview<span class="operator">.</span>page()<span class="operator">-</span><span class="operator">></span>setPreferredContentsSize(<span class="type"><a href="../qtcore/qsize.html">QSize</a></span>(desiredWidth<span class="operator">,</span> desiredHeight));
</pre>
<p>You can play around with this and find a suitable size for your device, but we will keep the default size for now.</p>
<a name="the-viewport-meta-tag"></a>
<h2 id="the-viewport-meta-tag">The 'viewport' Meta-Tag</h2>
<p>As some sites do not work with 960 pixels width or want to have control of how the page is laid out, Qt WebKit, Android, Firefox Mobile and the iPhone Safari browser support a meta-tag called <code>viewport</code>. This makes it possible for a web page to let the browser know how it wants to be shown. More info can be found in the <a href="http://developer.apple.com/safari/library/documentation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html">Safari Developer Library</a>.</p>
<p>You must connect the signal <code>QWebPage::viewportChangeRequested()</code> to a slot of your mobile web view and use what is provided by <a href="qwebpage-viewportattributes.html">QWebPage::ViewportAttributes</a> to update your viewport size, scale range, and so on.</p>
<a name="enabling-the-tiling"></a>
<h2 id="enabling-the-tiling">Enabling the Tiling</h2>
<p>We haven't actually enabled tiling yet, so let's go ahead and do that. That is very simple as it is basically a setting:</p>
<pre class="cpp">
<span class="type"><a href="qwebsettings.html">QWebSettings</a></span><span class="operator">::</span>globalSettings()<span class="operator">-</span><span class="operator">></span>setAttribute(<span class="type"><a href="qwebsettings.html">QWebSettings</a></span><span class="operator">::</span>TiledBackingStoreEnabled<span class="operator">,</span> <span class="keyword">true</span>);
</pre>
<p>Note that, if you are going to add animations to your zooming or scaling operations or want to implement fancy kinetic scrolling you might want to take a look at <a href="qgraphicswebview.html#tiledBackingStoreFrozen-prop">QGraphicsWebView::setTiledBackingStoreFrozen</a>(). With this, you can avoid updates to your tiles during an animation, for instance.</p>
<a name="avoiding-scrollable-subelements"></a>
<h2 id="avoiding-scrollable-subelements">Avoiding Scrollable Subelements</h2>
<p>One big issue with the above is that, iframes and sites using frames can contain scrollable subelements. That doesn't work well with the touch interaction model, as you want a finger swipe to scroll the whole page and not end up just scrolling a subframe. Most mobile browsers work around this by enabling something called frame flattening. Going straight to the point:</p>
<pre class="cpp">
<span class="type"><a href="qwebsettings.html">QWebSettings</a></span><span class="operator">::</span>globalSettings()<span class="operator">-</span><span class="operator">></span>setAttribute(<span class="type"><a href="qwebsettings.html">QWebSettings</a></span><span class="operator">::</span>FrameFlatteningEnable<span class="operator">,</span> <span class="keyword">true</span>);
</pre>
<p>This will make all frames from a web page expand themselves to the size of their contents, keeping us free of scrollable subareas.</p>
</div>
<!-- @@@qtwebkit-goes-mobile.html -->
<p class="naviNextPrevious footerNavi">
</p>
</div>
</div>
</div>
</div>
</div>
<div class="footer">
<p>
<acronym title="Copyright">©</acronym> 2017 The Qt Company Ltd.
Documentation contributions included herein are the copyrights of
their respective owners.<br> 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.<br> 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. </p>
</div>
</body>
</html>
|