Qt5.4开发文档翻译:从Qt WebKit 迁移至Qt WebEngine,Porting from Qt WebKit to Qt WebEngine
这篇文档讲述的是, 在将以Qt WebKit 的 QWebView API 开发的程序移植到以Qt WebEngine 的 QWebEngineView 来开发的过程中,要遵循的大致步骤。
在Qt WebEngine 中,与Qt WebKit 中的C++类等价的那些类,会带有" QWebEngine" 前缀,而不是" QWeb" 前缀。
Qt WebKit
#include <QWebHistory>
#include <QWebHistoryItem>
#include <QWebPage>
#include <QWebView>
Qt WebEngine
#include <QWebEngineHistory>
#include <QWebEngineHistoryItem>
#include <QWebEnginePage>
#include <QWebEngineView>
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 访问到。
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采用一种多进程的架构,因此,在应用程序中进行了某些调用之后应当返回到事件循环中,以异步地从Qt WebEngine 的渲染进程中接收到结果。必须提供一个函数指针、一个函子(functor)或一个lambda 表达式,以在结果可用时进行处理。
Qt WebKit
QWebPage *page = new QWebPage ;
QTextEdit *textEdit = new QTextEdit ;
// *textEdit被立即修改。
textEdit->setPlainText(page->toHtml());
textEdit->setPlainText(page->toPlainText());
Qt WebEngine (使用了C++11 中的lambda 函数)
QWebEnginePage *page = new QWebEnginePage ;
QTextEdit *textEdit = new QTextEdit ;
// *textEdit必须保持有效,直到该lambda 函数被调用。
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必须保持有效,直到该函子被调用。
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必须保持有效,直接该函子被调用。
page->toHtml(SetPlainTextFunctor(textEdit));
page->toPlainText(SetPlainTextFunctor(textEdit));
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 *)));
QWebFrame::evaluateJavaScript 被重命名了,现在叫做 QWebEnginePage::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; });
QWebEnginePage::setHtml 和 QWebEnginePage::setContent ,会像普通的HTTP 载入过程那样,异步地工作, 这一点与 QWebPage 中对应的方法不同。
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 类和方法,在Qt WebEngine 中是没有的。
Qt WebEngine 要求系统具有硬件加速。对于 一个 QGraphicsView ,在它没有附着到一个QGLWidget 视口上去的情况下,无法在其中支持一个网页视图,因此,这个特性超出我们的职责范围。 |
|
Qt WebEngine采用 一种多进程的架构,这就意味着,对于网页内部结构 的任何访问动作都必须异步完成, 其查询结果必须以回调函数来返回。 QWebElement API 被设计为同步访问的,因此,这方面的东西需要做一次完整的重新设计。 |
|
Qt WebKit 中的这个API 所封装的Web SQL Database 特性,已经被HTML5 标准所取代了。 |
|
QWebPluginFactory , QWebPage::setPalette , QWeb View::setRenderHints |
Qt WebEngine使用Skia 来渲染网页, 而不是使用 QPainter 或Qt。另外 , HTML5标准 中也引入了更好的替代内容, 都是Qt WebKit 中的那些原生控件插件所没有的。 |
已访问的链接,是由Qt WebEngine 自动进行持久化存储的。 |
张澜澜
Your opinionsHxLauncher: Launch Android applications by voice commands