从 Qt WebKit 移植到Qt WebEngine

以下部分包含将使用Qt WebKit QWebView API的应用程序移植到使用 Qt WebEngineQWebEngineView.

架构

Chromium 提供了自己的网络和绘画引擎,而Qt WebEngine 使用了这些引擎。除其他外,这使得Qt WebEngine 能比 Qt WebKit 为最新的 HTML5 规范提供更好、更可靠的支持。不过,Qt WebEngine 也因此比 Qt WebKit 更重,不能通过 C++ API 直接访问网络堆栈和 HTML 文档。

类名

Qt WebEngine 相当于 Qt WebKit 的 C++ 类的前缀是"QWebEngine "而不是"QWeb"

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 代表网页中的一个框架。每个 QWebPage 对象至少包含一个框架,即使用 QWebPage::mainFrame() 获得的主框架。其他框架将为 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 采用多进程架构,应用程序对某些方法的调用将立即返回结果,而结果则应通过回调机制异步接收。必须提供函数指针、函数器或 lambda 表达式,以便在结果可用时对其进行处理。

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 中使用 lambda 函数)

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 交互

Qt Network 的一些类,如QAuthenticator 的接口被重复使用,但与 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 QWebPageqDebug() << page->mainFrame()->evaluateJavaScript("'Java' + 'Script'");

Qt WebEngine (在 C++11 中使用 lambda 表达式)

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

setHtml 和 setContent

QWebEnginePage::setHtml 和 的异步执行方式与正常 HTTP 加载的方式相同,这与 QWebPage 对应程序不同。QWebEnginePage::setContent

设置内容可编辑

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 设计用于硬件加速。由于我们无法在 中支持 Web 视图类,除非它被附加到 QGLWidget 视口上,因此该功能已超出范围。QGraphicsView
QWebElementQt WebEngine 使用多进程架构,这意味着对页面内部结构的任何访问都必须异步完成,任何查询结果都必须通过回调返回。QWebElement API 是为同步访问而设计的,因此需要重新设计。
QWebDatabase该 API 在 Qt WebKit 中封装的 Web SQL 数据库功能已从 HTML5 标准中删除。
QWebPluginDatabase, QWebPluginFactory, QWebPluginInfo, QWebPage::setPalette, QWebView::setRenderHintsQt WebEngine 使用 Skia 渲染网页,而不是为此使用 或 Qt XML。HTML5 标准现在还提供了更好的替代方案,而这些方案在 Qt WebKit 引入本地控件插件时是不存在的。QPainter
QWebHistory 接口访问过的链接会被Qt WebEngine 自动持久化。
QWebPage::setContentEditable在最新的 HTML 标准中,任何文档元素都可以通过contentEditable 属性进行编辑。因此,runJavaScript 即可:page->runJavaScript("document.documentElement.contentEditable = true")
QWebPage::setLinkDelegationPolicy当链接被点击时,无法连接信号来运行 C++ 代码。不过,可以通过重载QWebEnginePage::acceptNavigationRequest() 函数,将链接点击委托给 Qt XML 应用程序,而不是由 HTML 处理引擎来处理。当 HTML 文档被用作用户界面的一部分,而不是用于显示外部数据(例如,显示结果列表)时,就有必要这样做。

注意: acceptNavigationRequest() 会启动加载过程,并请求被接受或拒绝之前发出loadStarted() 信号。因此,即使在委托请求后,也会出现返回falseloadFinished() 信号。

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.