View PDF in QML WebView

Refresh

March 2019

Views

0 time

1

I would like to view a PDF file in a WebView created in my QML code. I am importing QtWebView 1.1 and setting the url property to the path of the PDF file but I am getting this error:

[13044:12820:0314/144814.854:ERROR:in_progress_cache_impl.cc(192)] Cache is not initialized, cannot RetrieveEntry. [13044:12820:0314/144814.854:ERROR:in_progress_cache_impl.cc(176)] Cache is not initialized, cannot AddOrReplaceEntry. [13044:12820:0314/144814.854:ERROR:in_progress_cache_impl.cc(192)] Cache is not initialized, cannot RetrieveEntry.

When I use the same code to view an image it works. This question: Display PDF file with QWebView is close to what I want but QML does not seem to give me access to the settings method the way that C++ does (WebView docs). Is there some other way to do this?

1 answers

1

It seems that you are confusing elements, QWebView belongs to QtWebkit (uses Webkit) that no longer exists in Qt and that was replaced by Qt WebEngine (uses chromium). And another thing is WebView of Qt WebView that uses the native APIs (for example Android does not support Qt WebEngine but if WebView).

Qt WebEngine and Qt WebView does not support PDF visualization (Qt WenEngine will support it very soon) natively so a solution is to use some js library that does it as PDF.js so that is the alternative that I propose in base to an old answer.

*.pro

QT += quick webview
CONFIG += c++11
SOURCES += main.cpp
RESOURCES += qml.qrc

COPY_CONFIG = 3rdParty example.pdf
copy_cmd.input = COPY_CONFIG
copy_cmd.output = ${QMAKE_FILE_IN_BASE}${QMAKE_FILE_EXT}
copy_cmd.commands = $$QMAKE_COPY_DIR ${QMAKE_FILE_IN} ${QMAKE_FILE_OUT}
copy_cmd.CONFIG += no_link_no_clean
copy_cmd.variable_out = PRE_TARGETDEPS
QMAKE_EXTRA_COMPILERS += copy_cmd

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QtWebView>

class PDFJS: public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString version READ version WRITE setVersion NOTIFY versionChanged)
    QString m_version;
public:
    QString version() const{
        return m_version;
    }
    void setVersion(QString version){
        if (m_version == version)
            return;
        m_version = version;
        Q_EMIT versionChanged(m_version);
    }
    Q_SIGNAL  void versionChanged(QString version);
    Q_INVOKABLE QUrl getUrl(const QUrl & path){
        QString pdfjs_path = QDir::current().filePath(QString("3rdParty/pdfjs-%1-dist/web/viewer.html").arg(m_version));
        QUrl pdf_url = QUrl::fromLocalFile(pdfjs_path);
        QUrlQuery query;
        query.addQueryItem("file", path.toString());
        pdf_url.setQuery(query);
        return pdf_url;
    }
};

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QtWebView::initialize();
    QQmlApplicationEngine engine;
    PDFJS pdfjs;
    engine.rootContext()->setContextProperty("applicationDirPath", QGuiApplication::applicationDirPath());
    engine.rootContext()->setContextProperty("PDFJS", &pdfjs);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
    return app.exec();
}
#include "main.moc"

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtWebView 1.1

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("PDFJS Example")
    WebView{
        id: webview
        anchors.fill: parent
    }
    Component.onCompleted:{
        PDFJS.version = "2.1.266"
        webview.url = PDFJS.getUrl("file://" + applicationDirPath + "/example.pdf")
    }
}

enter image description here

You can find the complete project here

Update: only QML

.
|-- 3rdParty
|   `-- pdfjs-2.1.266-dist
|-- example.pdf
`-- main.qml

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtWebView 1.1

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("PDFJS Example")
    WebView{
        id: webview
        anchors.fill: parent
    }
    Component.onCompleted:{
        var pdfjs_path = Qt.resolvedUrl("3rdParty/pdfjs-2.1.266-dist/web/viewer.html")
        var path = Qt.resolvedUrl("example.pdf");
        var url = pdfjs_path + "?file=%1".arg(path)
        console.log(url)
        webview.url = url
    }
}

This part of the project you find here