Qt WebKit から Qt WebEngine への移植

以下のセクションでは、Qt WebKit QWebView API を使用しているアプリケーションをQt WebEngine QWebEngineView に移植する方法について説明します。

アーキテクチャ

Chromium は、Qt WebEngine が使用する独自のネットワークエンジンとペイントエンジンを提供します。これにより、Qt WebEngine は Qt WebKit よりも最新の HTML5 仕様に対応し、信頼性が向上しています。ただし、Qt WebEngine は Qt WebKit よりも重く、C++ API を通じてネットワークスタックや HTML ドキュメントに直接アクセスすることはできません。

クラス名

Qt WebKit の C++ クラスに相当する Qt WebEngine のプレフィックスは、"QWeb" ではなく"QWebEngine"です。

Qt WebKit

#include <QWebHistory>
#include <QWebHistoryItem>
#include <QWebPage>
#include <QWebView>

QWebHistory
QWebHistoryItem
QWebPage
QWebView

Qt WebEngine

#include <QWebEngineHistory>
#include <QWebEngineHistoryItem>
#include <QWebEnginePage>
#include <QWebEngineView>

QWebEngineHistory
QWebEngineHistoryItem
QWebEnginePage
QWebEngineView

Qt モジュール名

qmake プロジェクトファイル内

Qt WebKit

QT += webkitwidgets

Qt WebEngine

QT += webenginewidgets

ソースファイルにモジュールを含める

Qt WebKit

#include <QtWebKit/QtWebKit>
#include <QtWebKitWidgets/QtWebKitWidgets> // With Qt >= 4.8

Qt WebEngine

#include <QtWebEngineWidgets/QtWebEngineWidgets>

QWebFrame は QWebEnginePage に統合されました。

HTML フレームは、ウェブページをいくつかの領域に分割してコンテンツを個別に表現するために使用できます。

Qt WebKit では、QWebFrame が Web ページ内のフレームを表します。各 QWebPage オブジェクトには、QWebPage::mainFrame() を使用して取得したメインフレームが少なくとも 1 つ含まれています。追加のフレームは、1 つのフレームの外観と内容を定義する HTML<frame> 要素、またはテキストのブロック内にフレームを挿入する<iframe> 要素のために作成されます。

Qt WebEngine では、フレーム処理はQWebEnginePage クラスに統合されました。すべての子フレームはコンテンツの一部とみなされ、JavaScript でのみアクセスできるようになりました。QWebFrame クラスのメソッド(load() など)は、QWebEnginePage 自体から直接利用できるようになりました。

Qt WebKit

QWebPage page;
connect(page.mainFrame(), SIGNAL(urlChanged(const QUrl&)), SLOT(mySlotName()));
page.mainFrame()->load(url);

Qt WebEngine

QWebEnginePage page;
connect(&page, SIGNAL(urlChanged(const QUrl&)), SLOT(mySlotName()));
page.load(url);

一部のメソッドが結果を非同期で返すようになりました。

Qt WebEngine はマルチプロセスアーキテクチャを採用しているため、アプリケーションからいくつかのメソッドを呼び出すとすぐに結果を返します。関数ポインタ、ファンクタ、またはラムダ式は、結果が利用可能になったときに処理するために提供する必要があります。

Qt WebKit

QWebPage *page = new QWebPage;
QTextEdit *textEdit = new QTextEdit;
// *textEdit is modified immediately.
textEdit->setPlainText(page->toHtml());
textEdit->setPlainText(page->toPlainText());

Qt WebEngine (C++11 のラムダ関数付き)

QWebEnginePage *page = new QWebEnginePage;
QTextEdit *textEdit = new QTextEdit;
// *textEdit must remain valid until the lambda function is called.
page->toHtml([textEdit](const QString &result){ textEdit->setPlainText(result); });
page->toPlainText([textEdit](const QString &result){ textEdit->setPlainText(result); });

Qt WebEngine (メンバ関数をラップするファンクタ テンプレート付き)

template<typename Arg, typename R, typename C>
struct InvokeWrapper {
    R *receiver;
    void (C::*memberFun)(Arg);
    void operator()(Arg result) {
        (receiver->*memberFun)(result);
    }
};

template<typename Arg, typename R, typename C>
InvokeWrapper<Arg, R, C> invoke(R *receiver, void (C::*memberFun)(Arg))
{
    InvokeWrapper<Arg, R, C> wrapper = {receiver, memberFun};
    return wrapper;
}

QWebEnginePage *page = new QWebEnginePage;
QTextEdit *textEdit = new QTextEdit;
// *textEdit must remain valid until the functor is called.
page->toHtml(invoke(textEdit, &QTextEdit::setPlainText));
page->toPlainText(invoke(textEdit, &QTextEdit::setPlainText));

Qt WebEngine (通常のファンクタを使用)

struct SetPlainTextFunctor {
    QTextEdit *textEdit;
    SetPlainTextFunctor(QTextEdit *textEdit) : textEdit(textEdit) { }
    void operator()(const QString &result) {
        textEdit->setPlainText(result);
    }
};

QWebEnginePage *page = new QWebEnginePage;
QTextEdit *textEdit = new QTextEdit;
// *textEdit must remain valid until the functor is called.
page->toHtml(SetPlainTextFunctor(textEdit));
page->toPlainText(SetPlainTextFunctor(textEdit));

Qt WebEngine は QNetworkAccessManager と相互作用しません。

QAuthenticator のような Qt Network のいくつかのクラスは、そのインターフェイスのために再利用されましたが、Qt WebKit とは異なり、Qt WebEngine は独自の HTTP 実装を持っており、QNetworkAccessManager を経由することはできません。

まだサポートされているQNetworkAccessManager のシグナルとメソッドは、QWebEnginePage クラスに移動されました。

Qt WebKit

QNetworkAccessManager qnam;
QWebPage page;
page.setNetworkAccessManager(&qnam);
connect(&qnam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticate(QNetworkReply*,QAuthenticator*)));

Qt WebEngine

QWebEnginePage page;
connect(&page, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(authenticate(QNetworkReply*,QAuthenticator*)));

注意: Qt WebEngine では、認証をキャンセルするにはQAuthenticator を明示的に null に設定する必要があります:

*authenticator = QAuthenticator();

QNetworkAccessManager を省略すると、証明書の管理方法にも影響します。詳細については、証明書の管理を参照してください。

個々のメソッドに関する注意事項

evaluateJavaScript

QWebFrame::evaluateJavaScript は移動され、QWebEnginePage::runJavaScript という名前に変更されました。現在、ページのメインフレームでのみ JavaScript を実行することができ、結果は提供されたファンクタに非同期で返されます。

Qt WebKit

QWebPage *page = new QWebPage;
qDebug() << page->mainFrame()->evaluateJavaScript("'Java' + 'Script'");

Qt WebEngine (C++11 のラムダ式を使用)

QWebEnginePage *page = new QWebEnginePage;
page->runJavaScript("'Java' + 'Script'", [](const QVariant &result){ qDebug() << result; });

setHtml と setContent

QWebEnginePage::setHtml と は、QWebPage のものと異なり、通常の HTTP ロードと同じように非同期に実行されます。QWebEnginePage::setContent

setContentEditable

QWebPage::setContentEditable は、最新の HTML 標準の contentEditable 属性を通して、どんなドキュメント要素でも編集可能にすることができるので、同等のものはありません。そのため、QWebEnginePage::runJavaScript が必要です。

Qt WebKit

QWebPage page;
page.setContentEditable(true);

Qt WebEngine

QWebEnginePage page;
page.runJavaScript("document.documentElement.contentEditable = true");

利用できない Qt WebKit API

このリストにある Qt WebKit のクラスとメソッドは、Qt WebEngine では利用できません。

QGraphicsWebViewQt WebEngine はハードウェアアクセラレーションを使用するように設計されています。QGLWidget ビューポートにアタッチされない限り、QGraphicsView で Web ビュークラスをサポートできないため、この機能は対象外です。
QWebElementQt WebEngine はマルチプロセスアーキテクチャを使用しているため、ページの内部構造へのアクセスはすべて非同期で行わなければなりません。QWebElement API は同期アクセス用に設計されているため、完全な再設計が必要になります。
QWebDatabaseこの API が Qt WebKit でラップしていた Web SQL データベース機能は、HTML5 標準から削除されました。
QWebPluginDatabase, QWebPluginFactory, QWebPluginInfo, QWebPage::setPalette, QWebView::setRenderHintsQt WebEngine は Skia を使用して Web ページをレンダリングし、この目的のためにQPainter や Qt を使用していません。また、HTML5 標準は、Qt WebKit でネイティブ コントロール プラグインが導入されたときには利用できなかった、はるかに優れた代替手段を提供するようになりました。
QWebHistoryInterface訪問したリンクは、Qt WebEngine によって自動的に永続化されます。
QWebPage::setContentEditable最新の HTML 標準では、contentEditable 属性を使用することで、任意のドキュメント要素を編集可能にすることができます。そのため、runJavaScript がすべて必要です:page->runJavaScript("document.documentElement.contentEditable = true")
QWebPage::setLinkDelegationPolicyリンクがクリックされたときに C++ コードを実行するシグナルを接続する方法はありません。しかし、QWebEnginePage::acceptNavigationRequest ()関数をオーバーロードすることで、HTMLハンドラエンジンに処理させる代わりに、リンククリックをQtアプリケーションに委譲することができます。これは、HTMLドキュメントをユーザーインターフェースの一部として使用し、外部データを表示しない場合(例えば、結果のリストを表示する場合など)に必要です。

注: acceptNavigationRequest ()は読み込み処理を開始し、要求が受諾されるか拒否される前に loadStarted ()シグナルを発する。したがって、false を返すloadFinished() シグナルは、リクエストを委譲した後でも期待される。

©2024 The Qt Company Ltd. 本書に含まれる文書の著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。