diff --git a/examples/pdf/multipage/main.cpp b/examples/pdf/multipage/main.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..451521f806e1d73ca05f67172615979f73e6ed57
--- /dev/null
+++ b/examples/pdf/multipage/main.cpp
@@ -0,0 +1,69 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of The Qt Company Ltd nor the names of its
+**     contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QApplication>
+#include <QQmlApplicationEngine>
+
+int main(int argc, char* argv[])
+{
+    QApplication app(argc, argv);
+    QCoreApplication::setApplicationName("Qt Quick Multi-page PDF Viewer Example");
+    QCoreApplication::setOrganizationName("QtProject");
+    QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+
+    QQmlApplicationEngine engine;
+    engine.load(QUrl(QStringLiteral("qrc:///pdfviewer/viewer.qml")));
+    if (app.arguments().count() > 1) {
+        QUrl toLoad = QUrl::fromUserInput(app.arguments().at(1));
+        engine.rootObjects().first()->setProperty("source", toLoad);
+    }
+
+    return app.exec();
+}
diff --git a/examples/pdf/multipage/multipage.pro b/examples/pdf/multipage/multipage.pro
new file mode 100644
index 0000000000000000000000000000000000000000..5fff58fe111c131faf872072cea5c2c442b40915
--- /dev/null
+++ b/examples/pdf/multipage/multipage.pro
@@ -0,0 +1,14 @@
+TEMPLATE = app
+
+QT += qml quick pdf widgets
+
+SOURCES += main.cpp
+
+RESOURCES += \
+    viewer.qrc
+EXAMPLE_FILES = \
+    viewer.qml
+
+target.path = $$[QT_INSTALL_EXAMPLES]/pdf/multipage
+INSTALLS += target
+
diff --git a/examples/pdf/multipage/resources/document-open.svg b/examples/pdf/multipage/resources/document-open.svg
new file mode 100644
index 0000000000000000000000000000000000000000..bf23123a364de77e845628d82f76eb337022a9b5
--- /dev/null
+++ b/examples/pdf/multipage/resources/document-open.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#232629;
+      }
+      </style>
+  </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+       d="m4 4v24h24l-1-1h-22v-13h5l3-3h14v16l1 1v-21h-10l-3-3z"
+     class="ColorScheme-Text"
+     />
+</svg>
diff --git a/examples/pdf/multipage/resources/edit-clear.svg b/examples/pdf/multipage/resources/edit-clear.svg
new file mode 100644
index 0000000000000000000000000000000000000000..1c35aaf04f9001629c8e00d0d1d8a37fba373b84
--- /dev/null
+++ b/examples/pdf/multipage/resources/edit-clear.svg
@@ -0,0 +1,15 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#232629;
+      }
+      </style>
+  </defs>
+ <path
+    style="fill:currentColor;fill-opacity:1;stroke:none"
+	d="M 8 3 L 0.94335938 10.056641 L 0 11 L 0.94335938 11.943359 L 8 19 L 20.333984 19 L 22 19 L 22 3 L 20.333984 3 L 8 3 z M 11.320312 7 L 14 9.6796875 L 16.679688 7 L 18 8.3203125 L 15.320312 11 L 18 13.679688 L 16.679688 15 L 14 12.320312 L 11.320312 15 L 10 13.679688 L 12.679688 11 L 10 8.3203125 L 11.320312 7 z "
+    class="ColorScheme-Text"
+     transform="translate(1,1)"
+    />
+</svg>
diff --git a/examples/pdf/multipage/resources/edit-copy.svg b/examples/pdf/multipage/resources/edit-copy.svg
new file mode 100644
index 0000000000000000000000000000000000000000..9dd16877d6987ae0440f7ce71754002402bbfdf1
--- /dev/null
+++ b/examples/pdf/multipage/resources/edit-copy.svg
@@ -0,0 +1,15 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#232629;
+      }
+      </style>
+  </defs>
+ <path
+    style="fill:currentColor;fill-opacity:1;stroke:none"
+	d="m4 3v1 13h1 2 1v1 1h6l4-4v-1-7-1h-2v-3h-1-10-1m1 1h10v2h-7v1 9h-1-2v-12m4 3h8v7h-3-1v1 3h-4v-11"
+    class="ColorScheme-Text"
+     transform="translate(1,1)"
+    />
+</svg>
diff --git a/examples/pdf/multipage/resources/go-next-view-page.svg b/examples/pdf/multipage/resources/go-next-view-page.svg
new file mode 100644
index 0000000000000000000000000000000000000000..e453ddbecfac41444659b9f8c2bb025439eb03f2
--- /dev/null
+++ b/examples/pdf/multipage/resources/go-next-view-page.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#232629;
+      }
+      </style>
+  </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+     d="M 8.7070312 4 L 8 4.7070312 L 14.125 10.832031 L 15.292969 12 L 14.125 13.167969 L 8 19.292969 L 8.7070312 20 L 14.832031 13.875 L 16.707031 12 L 14.832031 10.125 L 8.7070312 4 z "
+     class="ColorScheme-Text"
+     />
+</svg>
diff --git a/examples/pdf/multipage/resources/go-previous-view-page.svg b/examples/pdf/multipage/resources/go-previous-view-page.svg
new file mode 100644
index 0000000000000000000000000000000000000000..b032309e9ad68135affb451fdab1a8f0f862f37a
--- /dev/null
+++ b/examples/pdf/multipage/resources/go-previous-view-page.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#232629;
+      }
+      </style>
+  </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+     d="M 15.292969 4 L 9.1679688 10.125 L 7.2929688 12 L 9.1679688 13.875 L 15.292969 20 L 16 19.292969 L 9.875 13.167969 L 8.7070312 12 L 9.875 10.832031 L 16 4.7070312 L 15.292969 4 z "
+     class="ColorScheme-Text"
+     />
+</svg>
diff --git a/examples/pdf/multipage/resources/rotate-left.svg b/examples/pdf/multipage/resources/rotate-left.svg
new file mode 100644
index 0000000000000000000000000000000000000000..90ce53c9ddf1a6ed9bab30a4c56fd51c2ac6759d
--- /dev/null
+++ b/examples/pdf/multipage/resources/rotate-left.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
+    <g color="#000" font-weight="400" fill="#474747">
+        <path d="M2 9v1c0 .265.093.53.281.719l3.72 3.719 3.718-3.72c.188-.187.281-.453.281-.718V9H9c-.265 0-.53.093-.719.281l-2.28 2.281-2.282-2.28A1.015 1.015 0 0 0 3 9z"/>
+        <path d="M8.5 3A3.515 3.515 0 0 0 5 6.5V12h2V6.5C7 5.66 7.66 5 8.5 5H13V3z"/>
+    </g>
+</svg>
diff --git a/examples/pdf/multipage/resources/rotate-right.svg b/examples/pdf/multipage/resources/rotate-right.svg
new file mode 100644
index 0000000000000000000000000000000000000000..7383d1c84e28fde8565860229ef97954aed970fb
--- /dev/null
+++ b/examples/pdf/multipage/resources/rotate-right.svg
@@ -0,0 +1,6 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
+    <g font-weight="400" fill="#474747">
+        <path d="M3 3v2h4.5C8.34 5 9 5.66 9 6.5V12h2V6.5C11 4.579 9.421 3 7.5 3z"/>
+        <path d="M6 9h1c.257 0 .529.13.719.313L10 11.592l2.281-2.28C12.471 9.13 12.743 9 13 9h1v1c0 .31-.09.552-.281.75L10 14.406 6.281 10.75C6.091 10.552 6 10.31 6 10z"/>
+    </g>
+</svg>
diff --git a/examples/pdf/multipage/resources/zoom-fit-best.svg b/examples/pdf/multipage/resources/zoom-fit-best.svg
new file mode 100644
index 0000000000000000000000000000000000000000..adf3026212b438a1ce92de7c67f389f88bc204e7
--- /dev/null
+++ b/examples/pdf/multipage/resources/zoom-fit-best.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#4d4d4d;
+      }
+      </style>
+  </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+     d="M 4 4 L 4 5 L 4 8 L 5 8 L 5 5 L 8 5 L 8 4 L 5 4 L 4 4 z M 12 4 L 10 6 L 14 6 L 12 4 z M 16 4 L 16 5 L 19 5 L 19 8 L 20 8 L 20 5 L 20 4 L 19 4 L 16 4 z M 7 7 L 7 17 L 17 17 L 17 7 L 7 7 z M 8 8 L 16 8 L 16 16 L 8 16 L 8 8 z M 6 10 L 4 12 L 6 14 L 6 10 z M 18 10 L 18 14 L 20 12 L 18 10 z M 4 16 L 4 19 L 4 20 L 8 20 L 8 19 L 5 19 L 5 16 L 4 16 z M 19 16 L 19 19 L 16 19 L 16 20 L 20 20 L 20 19 L 20 16 L 19 16 z M 10 18 L 12 20 L 14 18 L 10 18 z "
+     class="ColorScheme-Text"
+     />
+</svg>
diff --git a/examples/pdf/multipage/resources/zoom-fit-width.svg b/examples/pdf/multipage/resources/zoom-fit-width.svg
new file mode 100644
index 0000000000000000000000000000000000000000..985ee5205ced8ebeb5ecfd9d661caaa95fe16465
--- /dev/null
+++ b/examples/pdf/multipage/resources/zoom-fit-width.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#4d4d4d;
+      }
+      </style>
+  </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+     d="M 7 7 L 7 17 L 17 17 L 17 7 L 7 7 z M 8 8 L 16 8 L 16 16 L 8 16 L 8 8 z M 6 10 L 4 12 L 6 14 L 6 10 z M 18 10 L 18 14 L 20 12 L 18 10 z "
+     class="ColorScheme-Text"
+     />
+</svg>
diff --git a/examples/pdf/multipage/resources/zoom-in.svg b/examples/pdf/multipage/resources/zoom-in.svg
new file mode 100644
index 0000000000000000000000000000000000000000..efdc9f17d5476b33ea4eb12907a4ce74b0826f36
--- /dev/null
+++ b/examples/pdf/multipage/resources/zoom-in.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#232629;
+      }
+      </style>
+  </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+     d="M 4 4 L 4 6 L 5 6 L 5 5 L 6 5 L 6 4 L 4 4 z M 9 4 L 9 5 L 11 5 L 11 4 L 9 4 z M 13 4 L 13 5 L 15 5 L 15 4 L 13 4 z M 18 4 L 18 5 L 19 5 L 19 6 L 20 6 L 20 4 L 18 4 z M 12 8 L 12 9 L 14.292969 9 L 11 12.292969 L 11.707031 13 L 15 9.7070312 L 15 12 L 16 12 L 16 8 L 15 8 L 12 8 z M 4 9 L 4 11 L 5 11 L 5 9 L 4 9 z M 19 9 L 19 11 L 20 11 L 20 9 L 19 9 z M 19 13 L 19 15 L 20 15 L 20 13 L 19 13 z M 4 14 L 4 20 L 10 20 L 10 14 L 4 14 z M 5 15 L 9 15 L 9 19 L 5 19 L 5 15 z M 19 18 L 19 19 L 18 19 L 18 20 L 20 20 L 20 18 L 19 18 z "
+     class="ColorScheme-Text"
+     />
+</svg>
diff --git a/examples/pdf/multipage/resources/zoom-original.svg b/examples/pdf/multipage/resources/zoom-original.svg
new file mode 100644
index 0000000000000000000000000000000000000000..1b4080a03a31ab966a17389a062dd9d6ebd7eee2
--- /dev/null
+++ b/examples/pdf/multipage/resources/zoom-original.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#232629;
+      }
+      </style>
+  </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+     d="M 4 4 L 4 5 L 4 7 L 5 7 L 5 5 L 7 5 L 7 4 L 5 4 L 4 4 z M 17 4 L 17 5 L 19 5 L 19 7 L 20 7 L 20 5 L 20 4 L 19 4 L 17 4 z M 6 6 L 6 18 L 18 18 L 18 6 L 6 6 z M 7 7 L 17 7 L 17 17 L 7 17 L 7 7 z M 4 17 L 4 19 L 4 20 L 7 20 L 7 19 L 5 19 L 5 17 L 4 17 z M 19 17 L 19 19 L 17 19 L 17 20 L 20 20 L 20 17 L 19 17 z "
+     class="ColorScheme-Text"
+     />
+</svg>
diff --git a/examples/pdf/multipage/resources/zoom-out.svg b/examples/pdf/multipage/resources/zoom-out.svg
new file mode 100644
index 0000000000000000000000000000000000000000..fcde9e5262556c9a86ee5732da7aba7e79b4109f
--- /dev/null
+++ b/examples/pdf/multipage/resources/zoom-out.svg
@@ -0,0 +1,13 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
+  <defs id="defs3051">
+    <style type="text/css" id="current-color-scheme">
+      .ColorScheme-Text {
+        color:#232629;
+      }
+      </style>
+  </defs>
+ <path style="fill:currentColor;fill-opacity:1;stroke:none"
+     d="M 4 4 L 4 11 L 5 11 L 5 5 L 19 5 L 19 19 L 13 19 L 13 20 L 20 20 L 20 19 L 20 5 L 20 4 L 5 4 L 4 4 z M 15.292969 8 L 12 11.292969 L 12 9 L 11 9 L 11 13 L 12 13 L 15 13 L 15 12 L 12.707031 12 L 16 8.7070312 L 15.292969 8 z M 4 14 L 4 16 L 5 16 L 5 15 L 6 15 L 6 14 L 4 14 z M 8 14 L 8 15 L 9 15 L 9 16 L 10 16 L 10 14 L 8 14 z M 4 18 L 4 20 L 6 20 L 6 19 L 5 19 L 5 18 L 4 18 z M 9 18 L 9 19 L 8 19 L 8 20 L 10 20 L 10 18 L 9 18 z "
+     class="ColorScheme-Text"
+     />
+</svg>
diff --git a/examples/pdf/multipage/viewer.qml b/examples/pdf/multipage/viewer.qml
new file mode 100644
index 0000000000000000000000000000000000000000..d20ad4a5b71fee95cccd3a20b7a21e67cf3cee6c
--- /dev/null
+++ b/examples/pdf/multipage/viewer.qml
@@ -0,0 +1,276 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of The Qt Company Ltd nor the names of its
+**     contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.14
+import QtQuick.Controls 2.14
+import QtQuick.Layouts 1.14
+import QtQuick.Pdf 5.15
+import QtQuick.Shapes 1.14
+import QtQuick.Window 2.14
+import Qt.labs.platform 1.1 as Platform
+
+ApplicationWindow {
+    id: root
+    width: 800
+    height: 1024
+    color: "lightgrey"
+    title: document.title
+    visible: true
+    property alias source: document.source // for main.cpp
+
+    header: ToolBar {
+        RowLayout {
+            anchors.fill: parent
+            anchors.rightMargin: 6
+            ToolButton {
+                action: Action {
+                    shortcut: StandardKey.Open
+                    icon.source: "resources/document-open.svg"
+                    onTriggered: fileDialog.open()
+                }
+            }
+            /* TODO zoom & rotation
+            ToolButton {
+                action: Action {
+                    shortcut: StandardKey.ZoomIn
+                    enabled: view.sourceSize.width < 10000
+                    icon.source: "resources/zoom-in.svg"
+                    onTriggered: view.renderScale *= Math.sqrt(2)
+                }
+            }
+            ToolButton {
+                action: Action {
+                    shortcut: StandardKey.ZoomOut
+                    enabled: view.sourceSize.width > 50
+                    icon.source: "resources/zoom-out.svg"
+                    onTriggered: view.renderScale /= Math.sqrt(2)
+                }
+            }
+            ToolButton {
+                action: Action {
+                    icon.source: "resources/zoom-fit-width.svg"
+                    onTriggered: view.scaleToWidth(root.contentItem.width, root.contentItem.height)
+                }
+            }
+            ToolButton {
+                action: Action {
+                    icon.source: "resources/zoom-fit-best.svg"
+                    onTriggered: view.scaleToPage(root.contentItem.width, root.contentItem.height)
+                }
+            }
+            ToolButton {
+                action: Action {
+                    shortcut: "Ctrl+0"
+                    icon.source: "resources/zoom-original.svg"
+                    onTriggered: view.resetScale()
+                }
+            }
+            ToolButton {
+                action: Action {
+                    shortcut: "Ctrl+L"
+                    icon.source: "resources/rotate-left.svg"
+                    onTriggered: view.rotation -= 90
+                }
+            }
+            ToolButton {
+                action: Action {
+                    shortcut: "Ctrl+R"
+                    icon.source: "resources/rotate-right.svg"
+                    onTriggered: view.rotation += 90
+                }
+            }
+            */
+            ToolButton {
+                action: Action {
+                    icon.source: "resources/go-previous-view-page.svg"
+                    enabled: view.backEnbled
+                    onTriggered: view.back()
+                }
+                ToolTip.visible: enabled && hovered
+                ToolTip.delay: 2000
+                ToolTip.text: "go back"
+            }
+            SpinBox {
+                id: currentPageSB
+                from: 1
+                to: document.pageCount
+                editable: true
+                onValueChanged: view.currentPage = value - 1
+                Shortcut {
+                    sequence: StandardKey.MoveToPreviousPage
+                    onActivated: currentPageSB.value--
+                }
+                Shortcut {
+                    sequence: StandardKey.MoveToNextPage
+                    onActivated: currentPageSB.value++
+                }
+            }
+            ToolButton {
+                action: Action {
+                    icon.source: "resources/go-next-view-page.svg"
+                    enabled: view.forwardEnabled
+                    onTriggered: view.forward()
+                }
+                ToolTip.visible: enabled && hovered
+                ToolTip.delay: 2000
+                ToolTip.text: "go forward"
+            }
+            ToolButton {
+                action: Action {
+                    shortcut: StandardKey.Copy
+                    icon.source: "resources/edit-copy.svg"
+                    enabled: view.selectedText !== ""
+                    onTriggered: view.copySelectionToClipboard()
+                }
+            }
+            TextField {
+                id: searchField
+                placeholderText: "search"
+                Layout.minimumWidth: 200
+                Layout.fillWidth: true
+                Image {
+                    visible: searchField.text !== ""
+                    source: "resources/edit-clear.svg"
+                    anchors {
+                        right: parent.right
+                        top: parent.top
+                        bottom: parent.bottom
+                        margins: 3
+                        rightMargin: 5
+                    }
+                    TapHandler {
+                        onTapped: searchField.clear()
+                    }
+                }
+            }
+            Shortcut {
+                sequence: StandardKey.Find
+                onActivated: searchField.forceActiveFocus()
+            }
+            Shortcut {
+                sequence: StandardKey.Quit
+                onActivated: Qt.quit()
+            }
+        }
+    }
+
+    Platform.FileDialog {
+        id: fileDialog
+        title: "Open a PDF file"
+        nameFilters: [ "PDF files (*.pdf)" ]
+        onAccepted: document.source = file
+    }
+
+    Dialog {
+        id: passwordDialog
+        title: "Password"
+        standardButtons: Dialog.Ok | Dialog.Cancel
+        modal: true
+        closePolicy: Popup.CloseOnEscape
+        anchors.centerIn: parent
+        width: 300
+
+        TextField {
+            id: passwordField
+            placeholderText: qsTr("Please provide the password")
+            echoMode: TextInput.Password
+            width: parent.width
+            onAccepted: passwordDialog.accept()
+        }
+        onAccepted: document.password = passwordField.text
+    }
+
+    Dialog {
+        id: errorDialog
+        title: "Error loading " + document.source
+        standardButtons: Dialog.Ok
+        modal: true
+        closePolicy: Popup.CloseOnEscape
+        anchors.centerIn: parent
+        width: 300
+
+        Label {
+            id: errorField
+            text: document.error
+        }
+    }
+
+    PdfDocument {
+        id: document
+        onStatusChanged: {
+            if (status === PdfDocument.Error) errorDialog.open()
+            view.document = (status === PdfDocument.Ready ? document : undefined)
+        }
+        onPasswordRequired: {
+            passwordDialog.open()
+            passwordField.forceActiveFocus()
+        }
+    }
+
+    PdfMultiPageView {
+        id: view
+        anchors.fill: parent
+        document: root.document
+        searchString: searchField.text
+        onCurrentPageReallyChanged: currentPageSB.value = page + 1
+    }
+
+    footer: ToolBar {
+        height: statusLabel.implicitHeight * 1.5
+        Label {
+            id: statusLabel
+            anchors.verticalCenter: parent.verticalCenter
+            x: 6
+            property size implicitPointSize: document.pagePointSize(view.currentPage)
+            text: "page " + (currentPageSB.value) + " of " + document.pageCount +
+                  " original " + implicitPointSize.width.toFixed(1) + "x" + implicitPointSize.height.toFixed(1)
+            visible: document.pageCount > 0
+        }
+    }
+}
diff --git a/examples/pdf/multipage/viewer.qrc b/examples/pdf/multipage/viewer.qrc
new file mode 100644
index 0000000000000000000000000000000000000000..fa3561caf0a857175c02157a2262294c43c32b61
--- /dev/null
+++ b/examples/pdf/multipage/viewer.qrc
@@ -0,0 +1,17 @@
+<RCC>
+    <qresource prefix="/pdfviewer">
+        <file>viewer.qml</file>
+        <file>resources/edit-clear.svg</file>
+        <file>resources/edit-copy.svg</file>
+        <file>resources/go-next-view-page.svg</file>
+        <file>resources/go-previous-view-page.svg</file>
+        <file>resources/rotate-left.svg</file>
+        <file>resources/rotate-right.svg</file>
+        <file>resources/zoom-in.svg</file>
+        <file>resources/zoom-fit-best.svg</file>
+        <file>resources/zoom-fit-width.svg</file>
+        <file>resources/zoom-original.svg</file>
+        <file>resources/zoom-out.svg</file>
+        <file>resources/document-open.svg</file>
+    </qresource>
+</RCC>
diff --git a/src/pdf/quick/plugin.cpp b/src/pdf/quick/plugin.cpp
index 3c8077ff28dcdf3ec77f1aca5684119bb1947eb4..a831a09b63d280083643d49a49d92bf02f4d2ec4 100644
--- a/src/pdf/quick/plugin.cpp
+++ b/src/pdf/quick/plugin.cpp
@@ -89,6 +89,7 @@ public:
         qmlRegisterType<QQuickPdfSelection>(uri, 5, 15, "PdfSelection");
 
         qmlRegisterType(QUrl("qrc:/qt-project.org/qtpdf/qml/PdfPageView.qml"), uri, 5, 15, "PdfPageView");
+        qmlRegisterType(QUrl("qrc:/qt-project.org/qtpdf/qml/PdfMultiPageView.qml"), uri, 5, 15, "PdfMultiPageView");
     }
 };
 
diff --git a/src/pdf/quick/qml/PdfMultiPageView.qml b/src/pdf/quick/qml/PdfMultiPageView.qml
new file mode 100644
index 0000000000000000000000000000000000000000..36b194812891176521a3105bb8443466a21faad2
--- /dev/null
+++ b/src/pdf/quick/qml/PdfMultiPageView.qml
@@ -0,0 +1,180 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** BSD License Usage
+** Alternatively, you may use this file under the terms of the BSD license
+** as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of The Qt Company Ltd nor the names of its
+**     contributors may be used to endorse or promote products derived
+**     from this software without specific prior written permission.
+**
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+import QtQuick 2.15
+import QtQuick.Controls 2.15
+import QtQuick.Layouts 1.15
+import QtQuick.Pdf 5.15
+import QtQuick.Shapes 1.15
+import QtQuick.Window 2.15
+
+Item {
+    // public API
+    // TODO 5.15: required property
+    property var document: undefined
+    property real renderScale: 1
+    property string searchString
+    property string selectedText
+    property alias currentPage: listView.currentIndex
+    function copySelectionToClipboard() {
+        if (listView.currentItem !== null)
+            listView.currentItem.selection.copyToClipboard()
+    }
+    property alias backEnabled: navigationStack.backAvailable
+    property alias forwardEnabled: navigationStack.forwardAvailable
+    function back() { navigationStack.back() }
+    function forward() { navigationStack.forward() }
+    signal currentPageReallyChanged(page: int)
+
+    id: root
+    ListView {
+        id: listView
+        anchors.fill: parent
+        model: root.document === undefined ? 0 : root.document.pageCount
+        spacing: 6
+        highlightRangeMode: ListView.ApplyRange
+        highlightMoveVelocity: 2000 // TODO increase velocity when setting currentIndex somehow, too
+        onCurrentIndexChanged: {
+            navigationStack.currentPage = currentIndex
+            root.currentPageReallyChanged(currentIndex)
+        }
+        delegate: Rectangle {
+            id: paper
+            width: image.width
+            height: image.height
+            property alias selection: selection
+            property real __pageScale: image.paintedWidth / document.pagePointSize(index).width
+            Image {
+                id: image
+                source: document.source
+                currentFrame: index
+                asynchronous: true
+                fillMode: Image.PreserveAspectFit
+                width: document.pagePointSize(currentFrame).width
+                height: document.pagePointSize(currentFrame).height
+            }
+            Shape {
+                anchors.fill: parent
+                opacity: 0.25
+                visible: image.status === Image.Ready
+                ShapePath {
+                    strokeWidth: 1
+                    strokeColor: "blue"
+                    fillColor: "cyan"
+                    scale: Qt.size(paper.__pageScale, paper.__pageScale)
+                    PathMultiline {
+                        id: searchResultBoundaries
+                        paths: searchModel.matchGeometry
+                    }
+                }
+                ShapePath {
+                    fillColor: "orange"
+                    scale: Qt.size(paper.__pageScale, paper.__pageScale)
+                    PathMultiline {
+                        id: selectionBoundaries
+                        paths: selection.geometry
+                    }
+                }
+            }
+            PdfSearchModel {
+                id: searchModel
+                document: root.document
+                page: image.currentFrame
+                searchString: root.searchString
+            }
+            PdfSelection {
+                id: selection
+                document: root.document
+                page: image.currentFrame
+                fromPoint: Qt.point(textSelectionDrag.centroid.pressPosition.x / paper.__pageScale, textSelectionDrag.centroid.pressPosition.y / paper.__pageScale)
+                toPoint: Qt.point(textSelectionDrag.centroid.position.x / paper.__pageScale, textSelectionDrag.centroid.position.y / paper.__pageScale)
+                hold: !textSelectionDrag.active && !tapHandler.pressed
+                onTextChanged: root.selectedText = text
+            }
+            DragHandler {
+                id: textSelectionDrag
+                acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+                target: null
+            }
+            TapHandler {
+                id: tapHandler
+                acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
+            }
+            Repeater {
+                model: PdfLinkModel {
+                    id: linkModel
+                    document: root.document
+                    page: image.currentFrame
+                }
+                delegate: Rectangle {
+                    color: "transparent"
+                    border.color: "lightgrey"
+                    x: rect.x * paper.__pageScale
+                    y: rect.y * paper.__pageScale
+                    width: rect.width * paper.__pageScale
+                    height: rect.height * paper.__pageScale
+                    HoverHandler { cursorShape: Qt.PointingHandCursor } // 5.15 only (QTBUG-68073)
+                    TapHandler {
+                        onTapped: {
+                            if (page >= 0)
+                                listView.currentIndex = page
+                            else
+                                Qt.openUrlExternally(url)
+                        }
+                    }
+                }
+            }
+        }
+    }
+    PdfNavigationStack {
+        id: navigationStack
+        onCurrentPageJumped: listView.currentIndex = page
+        onCurrentPageChanged: root.currentPageReallyChanged(navigationStack.currentPage)
+    }
+}
diff --git a/src/pdf/quick/quick.pro b/src/pdf/quick/quick.pro
index a3bdfb45e2eb1817dc4c0fd4e9aee1d612ff76b4..a0a39d41459df004533d712c780b2641205a71fc 100644
--- a/src/pdf/quick/quick.pro
+++ b/src/pdf/quick/quick.pro
@@ -6,6 +6,7 @@ IMPORT_VERSION = 1.0
 #QMAKE_DOCS = $$PWD/doc/qtquickpdf.qdocconf
 
 PDF_QML_FILES = \
+    qml/PdfMultiPageView.qml \
     qml/PdfPageView.qml \
 
 QML_FILES += $$PDF_QML_FILES qmldir
diff --git a/src/pdf/quick/resources.qrc b/src/pdf/quick/resources.qrc
index a3f34189c7ba588537d0b61bb95f7c905d8a82cc..282610d4c21659fa6f3d2a60aea3c73acad13404 100644
--- a/src/pdf/quick/resources.qrc
+++ b/src/pdf/quick/resources.qrc
@@ -1,5 +1,6 @@
 <RCC>
   <qresource prefix="/qt-project.org/qtpdf">
+    <file>qml/PdfMultiPageView.qml</file>
     <file>qml/PdfPageView.qml</file>
   </qresource>
 </RCC>