从webkit到webengine
自从Qt5.6后引入了QWebEngine,摒弃了原先的QWebkit,这是一款基于chrome浏览器内核引擎,Qt webenginewidgets模块中提供了QWebEngineView这个视图控件来很不便的加载和显示网页,仅需如下几行:
QWebEngineView* webview = new QWebEngineView;webview->load(QUrl("https://www.baidu.com/"));webview->show();
QWebEngineView跳转问题
这段代码很容易运行起来,然而别快乐早了,接下来你会发现点页面上的链接或者百度到其它页面时无奈跳转,这是为什么呢?
因为咱们只是一个浏览器引擎,不是像firefox、chrome那样的浏览器,浏览器曾经提供了tab页去显示一个新的链接,所以这里咱们须要本人决定如何去显示新关上的链接。
有两种办法能够实现
1、咱们发现点击链接时时会收到urlChanged信号的,它附带的参数就是url地址,所以如果你想在本webview视图上显示这个页面就间接在绑定的槽函数里调用load(url)就ok了,如果你想实现向浏览器用另一tab来显示也是能够的,只需另外创立一个QWebEngineView,加载显示就好了,当然你也能够跳出一个对话框来显示,就想新关上一个浏览器窗口一样;
2、第二种办法就是重写createWindow办法,默认返回的是NULL,所以咱们看到的成果是无奈显示新的链接,因为你没有提供一个QWebEngineView给它嘛,在这个办法里有一个WebWindowType类型参数,
enum WebWindowType { WebBrowserWindow, WebBrowserTab, WebDialog };
能够看到就是第一种办法中咱们提到的三种显示,本浏览器窗口视图显示,另一tab页显示,跳出新的对话框显示,别离给你想实现的成果就好啦,简略而灵便。实际上js外面的window.open就会触发这个动作,调用到这个办法。
示例代码:
class HWebView : public QWebEngineView{ Q_OBJECTpublic: HWebView::HWebView(QWidget *parent) : QWebEngineView(parent){ }protected: virtual QWebEngineView *createWindow(QWebEnginePage::WebWindowType type){ HWebView* view = new HWebView; view->setAttribute(Qt::WA_DeleteOnClose); view->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); return view; }};
c++和JS交互
因为Qt自带的元对象模型Meta Object Model,信号与槽机制,使得c++和JS的交互异样简略而优雅,能够说比微软的com组件更加好用。
这里隆重退场的就是QWebChannel了,它应用了QWebSocket了,在C++端开了一个服务器端口,在JS客户端去连贯这个端口,而后利用qt的元对象模式,信号与槽机制进行替换,说的很简单,理论请看代码,很简略
class HWebContext : public QObject{ Q_OBJECTsignals: void sigClicked();public slots: void setAction(int action);};
QWebChannel* webchannel = new QWebChannel(m_webview);m_webview->page()->setWebChannel(webchannel);m_webContext = new HWebContext;webchannel->registerObject(QStringLiteral("content"), (QObject*)m_webContext);
首先咱们定义一个c++和JS进行交互的对象类,这个类须要继承自QObject,加上Q_OBJECT宏,定义一些信号和槽,这样就能够应用qt的信号与槽机制了.
而后new一个QWebChannel,与QWebEngineView外面的QWebEnginePage绑定起来,用registerObject去注册咱们定义的c++和JS进行交互的对象。
这样c++端的工作就实现了,c++端实际上开了一个端口去监听,提供了一个对象供js去应用。
在JS端须要做的工作如下:
<script type="text/javascript" src="./qwebchannel.js"></script>var g_context;function onClicked(){}window.onload=function(){ new QWebChannel(qt.webChannelTransport, function(channel) { g_context= channel.objects.content; g_context.sigClicked.connect(onClicked()) }); }g_context.setAction(0);
加载qwebchannel.js,这个文件在qt装置目录下搜寻能够找到,而后在窗口加载时利用QWebChannel,实际上是链接到了c++服务器端,获取到咱们在c++端注册的对象,content是c++端注册时为对象设置的字符串标识,为这个对象的信号连贯一个槽函数(js函数),这样c++端发出信号时就会去调用这个js函数,而js端调用c++槽函数更加简略,间接相似g_context.setAction(0)就能够了。
清理缓存、浏览记录、cookie
QWebEngineView view; view.page()->profile()->setPersistentCookiesPolicy(QWebEngineProfile::NoPersistentCookies); view.page()->profile()->clearHttpCache(); // 清理缓存 view.page()->profile()->clearAllVisitedLinks(); // 清理浏览记录 QWebEngineCookieStore* pCookie = view.page()->profile()->cookieStore(); pCookie->deleteAllCookies(); // 清理cookie pCookie->deleteSessionCookies(); // 清理会话cookie
部署
应用了webenginewidgets模块的,除了须要所需的库lib目录外,还有一些目录也须要一并拷贝过去,别离是libexec qml resources translations
此外须要在程序运行目录下写上配置文件qt.conf
[Paths]
Prefix=.
————————————————
版权申明:本文为CSDN博主「ithewei」的原创文章,遵循CC 4.0 BY-SA版权协定,转载请附上原文出处链接及本申明。
原文链接:https://blog.csdn.net/GG_SiMi...