从Qt WebKit移植到Qt WebEngine¶
Qt WebKit 和 Qt WebEngine API 之间差异的概述。
以下部分包含有关将使用Qt WebKit QWebView API的应用程序移植到使用Qt WebEngine QWebEngineView
的信息。
架构¶
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 元素创建的框架,该元素定义了单个框架的外观和内容,或者由
元素创建的框架,该元素在文本块中插入一个框架。
在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
也会影响证书的管理方式。更多信息,请参见Managing Certificates。
关于各个方法的注意事项¶
评估JavaScript¶
QWebFrame::evaluateJavaScript 已被移动并重命名为 runJavaScript
。目前只能在页面的主框架上运行 JavaScript,并且结果会异步返回到提供的函数对象。
Qt WebKit
QWebPage *page = new QWebPage; qDebug() << 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¶
setHtml
和 setContent
以异步方式执行,与普通的HTTP加载方式相同,这与它们的QWebPage对应物不同。
设置内容可编辑¶
QWebPage::setContentEditable 没有等效的方法,因为在最新的HTML标准中,任何文档元素都可以通过contentEditable属性设置为可编辑。因此,runJavaScript
就是所需要的全部。
Qt WebKit
QWebPage page; page.setContentEditable(true);
Qt WebEngine
QWebEnginePage page; page.runJavaScript("document.documentElement.contentEditable = true");