从Qt WebKit迁移到Qt WebEngine
以下章节包含有关将使用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 <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网络类,如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,并且结果将异步返回到提供的functor。
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
QWebEnginePage::setHtml和QWebEnginePage::setContent以类似正常HTTP加载的方式异步执行,与它们在QWebPage中的对应方法不同。
setContentEditable
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中可用。
QGraphicsWebView | Qt WebEngine旨在与硬件加速一起使用。因为我们无法在不将QGLWidget视口附加到之上时支持QGraphicsView的web视图类,因此该功能超出了范围。 |
QWebElement | Qt WebEngine使用多进程架构,这意味着对页面内部结构的任何访问都必须异步完成,任何查询结果都必须通过回调返回。QWebElement API是为同步访问设计的,这将需要一个完全的重设计。 |
QWebDatabase | 此API在Qt WebKit中封装的Web SQL Database功能已被HTML5标准删除。 |
QWebPluginDatabase, QWebPluginFactory, QWebPluginInfo, QWebPage::setPalette, QWebView::setRenderHints | Qt WebEngine使用Skia渲染网页,并不使用QPainter 或Qt来实现此目的。HTML5标准现在也提供了许多更好的备选方案,当在Qt WebKit中引入本地控件插件时,这些方案尚不可用。 |
QWebHistoryInterface | Qt WebEngine会自动保留已访问链接。 |
QWebPage::setContentEditable | 在最新的HTML标准中,任何文档元素都可以通过`contentEditable`属性进行编辑。所以只需要`runJavaScript`:`page->runJavaScript("document.documentElement.contentEditable = true")`。 |
QWebPage::setLinkDelegationPolicy | 当点击链接时,没有办法将信号连接以运行C++代码。然而,可以通过重载QWebEnginePage::acceptNavigationRequest() 函数,将链接点击委托给Qt应用程序处理,而不是由HTML处理引擎来处理这些点击事件。当使用HTML文档作为用户界面的一部分,并且不是为了显示外部数据时,例如显示结果列表时,这是必要的。 注意:acceptNavigationRequest() 在接受或拒绝请求之前开始加载过程并发射loadStarted() 信号。因此,即使委托了请求,也应预期返回 |
© 2024 The Qt Company Ltd. 本文档中包含的贡献的文档版权属于其各自的拥有者。提供的文档是在Free Software Foundation发布的GNU自由文档许可版1.3的条款下许可的。Qt及其相关标志是The Qt Company Ltd.在芬兰和/或其他国家/地区的商标。所有其他商标均为其各自所有者的财产。