Qt WebEngine 概述

Qt WebEngine 模块提供了一个网页浏览器引擎,使得在没有本地网页引擎的平台上,可以轻松地将来自万维网的内容嵌入到您的 Qt 应用程序中。

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

Qt WebEngine 架构

../_images/qtwebengine-architecture.png

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

页面渲染和JavaScript执行与GUI进程分离,进入Qt WebEngine进程。如果Qt库被捆绑到应用程序中,那么这是一个必须与应用程序一起发布的库。

Qt WebEngine 小部件模块

../_images/qtwebenginewidgets-model.png

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

所有页面都属于一个网页引擎配置文件,该文件包含共享的设置脚本cookies。配置文件可以用来隔离页面。一个典型的用例是用于隐私浏览模式的专用配置文件,在该模式下,不会永久保存任何信息。

注意

Qt WebEngine Widgets 模块使用 Qt Quick 场景图将网页的元素组合成一个视图。

内容使用显卡(GPU)的功能进行渲染。场景图则依赖于Qt渲染硬件接口作为GPU可能具备的不同功能和API的抽象层。有关如何调整渲染管道的更多建议,请参阅通过Qt渲染硬件接口进行渲染。

Qt WebEngine 模块

../_images/qtwebengine-model.png

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

Qt WebEngine 核心模块

Qt WebEngine 核心基于 Chromium 项目。Chromium 提供了自己的网络和绘图引擎,并与其依赖的模块紧密开发。尽管未使用 QtNetwork 堆栈,但其设置可以与 Qt WebEngine 同步。有关更多详细信息,请参阅 代理支持管理证书客户端证书QWebEngineCookieStore

注意

Qt WebEngine 基于 Chromium,但不包含或使用任何可能是由 Google 构建和发布的 Chrome 浏览器中的服务或附加组件。您可以在 概述 中找到有关 Chromium 和 Chrome 之间差异的更详细信息,该概述是 Chromium 项目 上游源代码树中文档的一部分。

使用的Chromium版本是在Qt WebEngine当前版本的Qt功能冻结时,最新稳定版Chrome所使用的版本。在每个补丁发布时,会从较新的Chrome版本中挑选额外的安全补丁,及时发布的安全补丁将在Qt补丁发布冻结前包含在内。如果Chrome在我们的发布窗口之外发布了关键修复,下一个补丁发布将加快,以确保在补丁细节公开之前发布修补后的Qt WebEngine。

如果您需要超出安全修复的较新Qt WebEngine,并且无法更新整个Qt,Qt WebEngine支持使用旧版本的Qt构建,直到最后一个Qt LTS。例如,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。这有助于缓解安全问题,并隔离由特定内容引起的崩溃。

将网页内容嵌入基于小部件的应用程序

使用QWebEngineView类以最简单的方式显示网页。因为它是一个小部件,你可以将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用于在页面上运行脚本,以及一个QWebEngineCookieStore用于访问Chromium的HTTP cookies。一个QWebEnginePage也可以直接指向一个脚本集合。

对于基于小部件的应用程序,除非将其放置在插件中,否则Web引擎会自动初始化。在这种情况下,必须在应用程序的主源文件中使用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和渲染进程之间共享,必须使用应用程序主源文件中的initialize来初始化web引擎,如下面的代码片段所示:

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

    QtWebEngineQuick::initialize();

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

    return app.exec();
}

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

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

脚本注入

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

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

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

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

  • @exclude

  • @include

  • @match

  • @name 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 Compiler构建的,并且应用程序在.qrc资源中包含了JavaScript文件,请考虑阅读Qt资源文件中的JavaScript文件部分。

管理证书

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

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

代理支持

Qt WebEngine 使用来自 Qt Network 的代理设置,并将它们转发到 Chromium 的网络堆栈。如果设置了 QNetworkProxy::applicationProxy,它也将用于 Qt WebEngine。如果启用了 QNetworkProxyFactory::usesSystemConfiguration(),代理设置将自动从系统中获取。不过,已安装的 QNetworkProxyFactory 的设置将被忽略。

如果设置了QNetworkProxy::user()和QNetworkProxy::password(),这些凭证将自动用于代理认证。用户需要提供有效的凭证,因为没有错误处理回调。

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

并非所有QNetworkProxy的属性都被Qt WebEngine支持。也就是说,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 将普通和高分辨率图像捆绑到 qtwebengine_resources_100p.pakqtwebengine_resources_200p.pak 文件中。根据目标分辨率,需要部署其中一个或两个文件。

更多信息,请参见高DPI。

使用WebEngine核心

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

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

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

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

平台说明

Qt WebEngine 目前仅支持 Windows、Linux 和 macOS。由于 Chromium 的构建要求,它通常还需要比 Qt 其他部分更新的编译器。更多详情请参阅 Qt WebEngine 平台说明