从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也相对比较重,并且不提供通过C++ API直接访问网络栈和HTML文档的能力。
类名称#
Qt WebEngine等效的是使用前缀“QWebEngine”而不是“QWeb”的Qt WebKit C++类。
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已移动并更名为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对应物。
setContentEditable#
QWebPage::setContentEditable没有等效功能,因为任何文档元素都可以通过最新HTML标准中的contentEditable属性使其可编辑。因此,只需要runJavaScript
。
Qt WebKit
QWebPage page; page.setContentEditable(true);
Qt WebEngine
QWebEnginePage page; page.runJavaScript("document.documentElement.contentEditable = true");