共计 3033 个字符,预计需要花费 8 分钟才能阅读完成。
从 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_OBJECT
public:
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_OBJECT
signals: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…