Qt WebEngine 概述#

Qt WebEngine 模块提供了一个网页浏览器引擎,使得在没有本地网页引擎的平台中嵌入互联网内容变得简单。

Qt WebEngine 提供了 C++ 类和 QML 类型用于渲染 HTML、XHTML 和 SVG 文档,通过级联样式表 (CSS) 进行样式设计并使用 JavaScript 进行脚本编写。通过在 HTML 元素上使用 contenteditable 属性,用户可以对 HTML 文档进行完全编辑。

Qt WebEngine 架构#

../_images/qtwebengine-architecture.png

Qt WebEngine 中的功能分为以下模块:

页面渲染和 JavaScript 执行被分开到 Qt WebEngine 进程中,它是一个库,如果 Qt 库被打包到应用程序中,则必须与应用程序一起分发。

Qt WebEngine Widgets 模块#

../_images/qtwebenginewidgets-model.png

Web 引擎视图 是 Qt WebEngine 模块的主要小部件组件。它可以用于各种应用程序以加载网页内容。在一个视图中,Web 引擎页面 包含一个负责网页内容的主框架,以及用户导航链接的 历史记录操作。视图和页面非常相似,因为它们提供了一组共同的功能。

所有页面都属于一个 Web 引擎配置文件,其中包含共享的 设置脚本cookie。配置文件可以用于使页面彼此隔离。一个典型的用例是为 隐私浏览 模式创建一个专门的配置文件,其中不会永久保存任何信息。

注意

Qt WebEngine Widgets 模块使用 Qt Quick 场景图来组合网页元素为一个视图。这意味着 UI 进程需要 OpenGL ES 2.0 或 OpenGL 2.0 进行渲染。

Qt WebEngine 模块#

../_images/qtwebengine-model.png

Qt WebEngine QML 实现包含与 Qt WebEngine Widgets 实现相同的元素,但是没有可以单独访问的 Web 引擎页面。支持的页面功能已集成到 Web 引擎视图中。

Qt WebEngine Core 模块#

Qt WebEngine 核心基于Chromium 项目 。Chromium 提供了自己的网络和渲染引擎,并与依赖模块紧密结合开发。即使不使用 QtNetwork 堆栈,其设置也可以与 Qt WebEngine 保持同步。请参阅代理支持证书管理客户端证书QWebEngineCookieStore以了解更多信息。

注意

Qt WebEngine 基于Chromium,但不包含或使用Chrome浏览器中可能存在的任何服务或插件,Chrome浏览器由Google构建和提供。您可以在概述中找到关于Chromium和Chrome之间区别的详细信息,该概述是Chromium 项目上游源树文档的一部分。

所使用的Chromium版本是Qt WebEngine当前版本特性冻结时最新稳定Chrome版本所使用的版本。在每个补丁发布时,会从较新的Chrome版本中挑选取补丁安全修复。对于Qt补丁发布冻结期间发布的补丁安全修复也会包含在内。如果Chrome在我们的发布窗口外发布关键修复,则将加快下一个补丁发布的速度,以确保在补丁详细信息公布之前发布已修复的Qt WebEngine。

如果您需要超过安全修复的新Qt WebEngine,并且不能更新所有Qt,Qt WebEngine支持使用Qt最新的LTS版本构建旧版本的Qt。例如,Qt WebEngine 6.3、6.4和6.5都可以使用Qt 6.2构建。在Qt LTS版本中,Qt WebEngine可以被较新的版本完全替换,以简化安全修补。

相关的Chromium版本也可以使用qWebEngineChromiumVersion()方法读取,并使用qWebEngineChromiumSecurityPatchVersion()读取当前的安全修补级别。您还可以在Qt WebEngine源中的CHROMIUM_VERSION文件中找到这些版本。

Qt WebEngine 进程#

Qt WebEngine 进程是一个用于渲染网页和执行JavaScript的独立的可执行文件。这有助于缓解由于特定内容引发的安全问题和崩溃。

将Web内容内嵌到基于小部件的应用程序中#

使用QWebEngineView类以最简单的方式显示网页。因为它是一个小部件,您可以将其嵌入到您的表单中,并使用它的便利函数下载和显示网站。

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

一个 QWebEngineView 实例包含一个 QWebEnginePageQWebEnginePage 可拥有一个 QWebEngineHistory ,提供对页面导航历史的访问,并包含几个对网页执行操作的 QAction 对象。此外,QWebEnginePage 还具有在页面的主帧中运行 JavaScript 代码以及在显示自定义身份验证对话框等特定事件上定制处理程序的能力。

每个 QWebEnginePage 都属于一个 QWebEngineProfile,它可有用于指定页面设置的 QWebEngineSettings,一个用于在页面上运行脚本的 QWebEngineScriptCollection,以及一个用于访问铬的 HTTP 甜点的 QWebEngineCookieStore。一个 QWebEnginePage 也可以直接指向一个脚本集合。

对于以小部件为基础的应用程序,除非它被放在插件中,否则网页引擎会自动初始化。在这种情况下,必须通过使用 initialize 在应用程序主源文件中进行初始化,如下代码片段所示

int main(int argc, char **argv)
{
    QtWebEngineQuick::initialize();

    QApplication app(argc, argv);

    QMainWindow window;
    window.show();

    return app.exec();
}

将网络内容嵌入到 Qt Quick 应用程序中#

WebEngineView QML 类型允许 Qt Quick 应用程序渲染动态网络内容区域。一个 ** WebEngineView ** 类型可以与其他 QML 类型共享屏幕,或者根据 Qt Quick 应用程序中的指定覆盖整个屏幕。

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

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QtWebEngineQuick::initialize();

    QQmlApplicationEngine engine;
    engine.load(QUrl("qrc:/main.qml"));

    return app.exec();
}

应用程序可以加载网页到 WebEngineView 中,通过URL或HTML字符串进行,并在会话历史中导航。默认情况下,不同页面的链接会在同一个 WebEngineView 对象中加载,但网站可能请求将它们作为新标签页、窗口或对话框打开。

以下示例QML应用程序通过以下 url 属性加载网页

脚本注入#

Qt WebEngine不允许直接访问页面的文档对象模型(DOM)。然而,可以通过注入脚本来检查和修改DOM。

当文档准备就绪时,页面DOM被构建,通常在页面完全加载后。因此,在文档创建后立即执行脚本来操作DOM不适合,必须等待DOM加载完成。

此外,注入的脚本与页面上执行的其它脚本共享相同的 世界,可能会导致冲突。为了避免这种情况,QWebEngineScript 类和 WebEngineScript QML类型提供了 Chromium API 的实现,用于 内容脚本扩展。它们指定运行的脚本、注入点以及脚本运行的世界。这允许在一个世界中访问DOM并操作它。

自 Qt 5.8 起,Qt WebEngine支持使用以下类似 Greasemonkey 的属性来增强脚本

  • @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");

如果您的 WebEngine 应用程序使用 Qt Quick 编译器构建,并且应用程序在 .qrc 资源内部包含 JavaScript 文件,请考虑阅读 Qt 资源文件中的JavaScript文件 部分。

管理证书#

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

WebEngineCertificateError::type 和 Type 枚举提供有关可能发生的证书错误类型的详细信息。这些错误可以通过使用 certificateError QML 方法或连接到 certificateError 信号来处理。

代理支持#

Qt WebEngine 使用 Qt Network 的代理设置,并将其转发到 Chromium 的网络堆栈。如果设置了 QNetworkProxy::applicationProxy,它也将用于 Qt WebEngine。如果启用 QNetworkProxyFactory::usesSystemConfiguration(),则将从系统中自动检索代理设置。但是,将忽略已安装的 QNetworkProxyFactory 的设置。

如果设置了 QNetworkProxy::user() 和 QNetworkProxy::password(),将自动使用这些凭据进行代理认证。由于没有错误处理回调,因此用户必须提供有效的凭据。

如果没有使用 QNetworkProxy 设置凭据,但代理需要认证,将触发 proxyAuthenticationRequired。对于 Qt Quick,将显示一个对话框。

Qt WebEngine 不支持 QNetworkProxy 的所有属性。也就是说,考虑了 QNetworkProxy::type(),QNetworkProxy::hostName() 和 QNetworkProxy::port()。所有其他代理设置,如 QNetworkProxy::rawHeader(),都将被忽略。

高 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.pakqtwebengine_resources_200p.pak 文件中。根据目标分辨率的设置,可能需要部署一个或两个这些文件。

有关更多信息,请参阅高 DPI。

使用 WebEngine 核心#

Qt WebEngine Core 为 Qt WebEngine 和 Qt WebEngine Widgets 提供了一个 API,用于处理为 Chromium 的网络堆栈发出的 URL 请求,并访问其 HTTP Cookie。

通过实现 QWebEngineUrlRequestInterceptor 接口并在配置文件上安装拦截器,可以拦截、阻止和修改 URL 请求(QWebEngineUrlRequestInfo),在它们到达 Chromium 的网络堆栈之前。

可以为配置文件注册一个QWebEngineUrlSchemeHandler,以支持自定义URL协议。然后,将针对该协议的请求作为requestStarted()方法中的QWebEngineUrlRequestJob对象发出。

QWebEngineCookieStore类提供访问Chromium的HTTPcookie的功能。这些函数可用于同步QNetworkAccessManager与cookie,以及在导航期间设置、删除和截获cookie。

平台注意事项#

Qt WebEngine目前只支持Windows、Linux和macOS。由于Chromium构建需要,它通常还需要一个比Qt其他部分更新的编译器。有关详细信息,请参阅Qt WebEngine平台注意事项