Qt WebEngine 概述

Qt WebEngine 模块提供 Web 浏览器引擎,使之更易于把 WWW (万维网) 内容嵌入到没有本机 Web 引擎平台的 Qt 应用程序中。

Qt WebEngine 提供 C++ 类和 QML 类型为渲染 HTML XHTML SVG 文档,样式化使用 CSS (级联样式表),及脚本化采用 JavaScript。HTML 文档可以完全可编辑,通过用户透过使用 contenteditable 属性在 HTML 元素。

Qt WebEngine 体系结构

Qt WebEngine 功能被分为以下模块:

页面渲染和 JavaScript 执行由 GUI 进程分离到 Qt WebEngine Processes。它是必须与应用程序一起出货的库,若 Qt 库被绑定到应用程序中。

Qt WebEngine Widgets 模块

Web engine view 是 Qt WebEngine 模块的主要 Widget 组件。它可以被用于各种应用程序中以加载 Web 内容。在视图中, Web 引擎页面 保持负责 Web 内容的主框架,导航链接 history ,和 actions 。视图和页面非常相似,因为它们提供了一套常见函数。

所有页面属于 Web 引擎配置文件 包含共享 settings , scripts ,和 Cookie 。配置文件可以被用于把页面彼此隔离。典型用例是专用配置文件为 隐私浏览 模式,没有永久保存信息的位置。

注意: Qt WebEngine Widgets 模块使用 Qt Quick scene graph 把网页元素组合成一视图。这意味着 UI 进程要求 OpenGL ES 2.0 或 OpenGL 2.0 为其渲染。

Qt WebEngine 模块

Qt WebEngine QML 实现包含如 Qt WebEngine Widgets 实现相同的元素,除不可单独访问 Web 引擎页面外。支持的页面功能已集成到 Web 引擎视图。

Qt WebEngine Core 模块

Qt WebEngine 核心基于 Chromium 工程 。Chromium 提供自己的网络和描绘引擎,并与其从属模块紧密协调开发。

注意: Qt WebEngine 基于 Chromium,但不包含或使用任何可能由 Google 构建 交付属于 Chrome 浏览器的服务或附件。可以找到有关 Chromium 和 Chrome 之间差异的更多详细信息,在此 概述 属于文档编制在 Chromium 工程 上游源代码树。

This version of Qt WebEngine is based on Chromium version 56.0.2924.122, with additional security fixes from newer versions.

Qt WebEngine Process

Qt WebEngine Process 是用于渲染网页并执行 JavaScript 的单独可执行文件。这能缓解安全问题并隔离由特定内容导致的崩溃。

把 Web 内容嵌入基于 Widget 的应用程序

使用 QWebEngineView 类以最简单方式显示网页。因为它是 Widget,可以嵌入 QWebEngineView 到表单中,并使用其方便函数去下载和显示网站。

QWebEngineView *view = new QWebEngineView(parent);
view->load(QUrl("http://www.qt.io/"));
view->show();
							

QWebEngineView 实例有一 QWebEnginePage . QWebEnginePage 可以有 QWebEngineHistory 提供访问页面的导航历史和几个 QAction 对象在网页上应用动作。此外, QWebEnginePage 有能力在页面主框架的上下文中运行 JavaScript 代码,并启用针对特定事件 (像展示自定义身份验证对话框) 的定制处理程序。

QWebEnginePage 属于 QWebEngineProfile 可以拥有 QWebEngineSettings 用于指定页面设置, QWebEngineScriptCollection 用于在页面上运行脚本,和 QWebEngineCookieStore 用于访问 Chromium 的 HTTP Cookie。 QWebEnginePage 也可以直接指向脚本集合。

对于基于 Widget 的应用程序,Web 引擎被自动初始化,除非它被放置在插件中。在此情况下,它必须在应用程序 main 源文件中被初始化通过使用 QtWebEngine::initialize ,如由以下代码段所阐明的:

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    QtWebEngine::initialize();
    QMainWindow window;
    window.show();
    return app.exec();
}
							

把 Web 内容嵌入 Qt Quick 应用程序

WebEngineView QML 类型允许 Qt Quick 应用程序渲染动态 Web 内容区域。 WebEngineView 类型可以与其它 QML 类型共享屏幕,或围绕在 Qt Quick 应用程序中指定的全屏。

为确保 OpenGL 上下文可以在 GUI 和渲染进程之间共享,必须初始化 Web 引擎通过使用 QtWebEngine::initialize 在应用程序主源文件中,如以下代码段所示:

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QtWebEngine::initialize();
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    return app.exec();
}
							

应用程序可以把页面加载到 WebEngineView ,使用 URL 或 HTML 字符串,并在会话历史中导航。默认情况下,指向不同页面的链接会被加载在同一 WebEngineView 对象,但网站可能要求把它们打开作为新选项卡、窗口或对话框。

以下样本 QML 应用程序加载网页使用 url 特性:

import QtQuick 2.0
import QtQuick.Window 2.0
import QtWebEngine 1.0
Window {
    width: 1024
    height: 750
    visible: true
    WebEngineView {
        anchors.fill: parent
        url: "http://www.qt.io"
    }
}
							

脚本注入

Qt WebEngine 不允许直接访问页面的 DOM (文档对象模型)。无论如何,DOM 可以被审查和改编通过注入脚本。

页面的 DOM 是当文档就绪时被构造的,通常是在页面完全加载时。所以,在文档被创建后尽快执行脚本不适合 DOM 操作,因为操作必须等待直到 DOM 就绪。

此外,注入的脚本共享相同 world 如在页面上的其它执行脚本,可能导致冲突。要避免这, QWebEngineScript 类和 WebEngineScript QML 类型提供了 Chromium API 实现为 内容脚本扩展 。它们指定要运行的脚本、注入点及脚本运行的世界。这使在世界中能够操纵访问 DOM。

从 Qt 5.8 起,Qt WebEngine 支持增强脚本通过使用以下 Greasemonkey-like 属性 :

  • @exclude <regexp>
  • @include <regexp>
  • @match <regexp>
  • @name <free text>
  • @run-at [document-start|document-end|document-idle]

属性确定是否以及何时 用户脚本 运行。它们必须立即被放置在脚本的开头,在 ==UserScript== 注释:

// ==UserScript==
// @include http://*.qt.io/*
// @exclude http://wiki.qt.io/*
// ==/UserScript==
window.alert("Page is from qt.io, but not wiki.qt.io");
							

管理证书

Qt WebEngine 使用自己的网络堆栈,因此 QSslConfiguration 不被用于打开 SSL 连接。相反,Qt WebEngine 使用来自操作系统的根 CA 证书去验证对等方的证书。

WebEngineCertificateError::error and QWebEngineCertificateError::Error 枚举提供可能发生证书错误的类型的有关信息。可以处理错误通过使用 WebEngineView::certificateError QML 方法或通过重实现 QWebEnginePage::certificateError 函数。

代理支持

Qt WebEngine 使用代理设置来自 Qt Network ,并把它们转发给 Chromium 的网络堆栈。若 QNetworkProxy::applicationProxy 有设置,也会用于 Qt WebEngine。若 QNetworkProxyFactory::usesSystemConfiguration () 被启用,自动检索系统代理设置。设置来自安装的 QNetworkProxyFactory 将被忽略,虽然。

并非所有特性为 QNetworkProxy 都被 Qt WebEngine 所支持。也就是说, QNetworkProxy::type (), QNetworkProxy::hostName () 和 QNetworkProxy::port () 会考虑在内。所有其它代理设置,如 QNetworkProxy::rawHeader (), QNetworkProxy::user (),或 QNetworkProxy::password () 被忽略。

If a proxy requires authentication, QWebEnginePage::proxyAuthenticationRequired 被发射。对于 Qt Quick,展示对话框。

高 DPI 支持

要支持高 DPI (每英寸点数) 设备,推荐应用程序属性 Qt::AA_EnableHighDpiScaling 设置为启用基于监视器的像素密度的自动比例缩放。在 Qt WebEngine 应用程序中,比例缩放影响默认缩放因子和滚动条尺寸。

例如:

int main(int argc, char *argv[])
{
  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
  QApplication app(argc, argv);
  // ...
}
							

QT WebEngine 把普通和高 DPI (每英寸点数) 分辨率图像绑定到 qtwebengine_resources_100p.pak and qtwebengine_resources_200p.pak 文件。根据目标分辨率,需要部署这些文件中的一个或两个。

更多信息,见 高 DPI 显示 .

使用 WebEngine Core

Qt WebEngine Core 提供由 Qt WebEngine 和 Qt WebEngine Widgets 共享的 API,用于处理为 Chromium 网络堆栈发出的 URL 请求及访问其 HTTP Cookie。

实现 QWebEngineUrlRequestInterceptor 接口并在配置文件中安装拦截器启用拦截、阻塞及修改 URL 请求 ( QWebEngineUrlRequestInfo ) 在它们到达 Chromium 网络堆栈之前。

QWebEngineUrlSchemeHandler 可以被注册对于配置文件以添加支持自定义 URL 方案。方案请求然后会被发送给 QWebEngineUrlSchemeHandler::requestStarted () 作为 QWebEngineUrlRequestJob 对象。

QWebEngineCookieStore 类提供访问 Chromium HTTP Cookie 的函数。可以使用这些函数同步 Cookie 与 QNetworkAccessManager ,及在导航期间设置、删除、拦截 Cookie。

平台注意事项

Qt WebEngine 目前只支持 Windows Linux 及 macOS . Due to Chromium build requirements it also often requires a newer compiler than the rest of Qt. See Qt WebEngine 平台注意事项 进一步了解细节。

Qt WebEngine 取代 Qt WebKit 模块基于 WebKit 工程,但没有主动同步上游 WebKit code since Qt 5.2 and has been deprecated in Qt 5.5. For tips on how to change a Qt WebKit widgets application to use Qt WebEngine widgets, see 从 Qt WebKit 移植到 Qt WebEngine .

Qt WebView 模块允许在可用平台上使用本机 Web 浏览器。

Qt WebChannel 模块可以被用于创建双向通信通道介于 QObject 对象在 C++ 侧和 JavaScript 在 QML 侧。