1、简单展示如何用QWebEngieView 显示百度网页
CccTestWebView.h#ifndef CCCTESTWEBVIEW_H #define CCCTESTWEBVIEW_H #includeCccTestWebView.cppclass QWebEngineView; class CccTestWebView : public QWidget { Q_OBJECT public: explicit CccTestWebView(QWidget *parent = nullptr); ~CccTestWebView(); void initWidget(); private: QWebEngineView* m_pWebView = nullptr; }; #endif // FORM_H
#include "CccTestWebView.h" #includemain.cpp#include CccTestWebView::CccTestWebView(QWidget *parent) :QWidget(parent) { initWidget(); } CccTestWebView::~CccTestWebView() { } void CccTestWebView::initWidget() { resize(420,680); auto mainLayout = new QVBoxLayout(this); mainLayout->setSpacing(0); mainLayout->setMargin(0); m_pWebView = new QWebEngineView(this); m_pWebView->load(QUrl("http://www.baidu.com")); mainLayout->addWidget(m_pWebView); }
#include结果#include "CccTestWebView.h" int main(int argc, char *argv[]) { QApplication a(argc, argv); CccTestWebView w; w.show(); return a.exec(); }
编译顺利的话你会正确的下显示百度的网页,如果报错看是不是事没有把webenginewidgets加入到.pro项目配置文件中去。但是此时你点击任何一个链接是不可以跳转到二级网页链接中去的。你需要自定义webengineview.
2、继承QWebEngineView,实现createWindow函数
CccWebEngineView.h#ifndef CCCWEBENGINEVIEW_H #define CCCWEBENGINEVIEW_H #includeCccWebEngineView.cpp#include #include class CccWebEngineView : public QWebEngineView { Q_OBJECT public: explicit CccWebEngineView(QWidget* parent = nullptr); ~CccWebEngineView(); virtual QWebEngineView* createWindow(QWebEnginePage::WebWindowType type) override; private: QUrl m_url; }; #endif // CCCWEBENGINEVIEW_H
#include "CccWebEngineView.h"
CccWebEngineView::CccWebEngineView(QWidget *parent)
:QWebEngineView(parent)
{
//TODO: 链接hover时改变m_url的值
connect(this->page(), &QWebEnginePage::linkHovered, this, [this](const QString &url){
m_url.setUrl(url);
});
connect(this->page(), &QWebEnginePage::urlChanged, this, [this](const QUrl &url){
m_url = url;
});
}
CccWebEngineView::~CccWebEngineView()
{
}
QWebEngineView *CccWebEngineView::createWindow(QWebEnginePage::WebWindowType type)
{
Q_UNUSED(type);
if(!m_url.isEmpty())
{
this->load(m_url);//加载新的url
}
return nullptr;
}
CccTestWebView.h
#ifndef CCCTESTWEBVIEW_H #define CCCTESTWEBVIEW_H #includeCccTestWebView.cppclass CccWebEngineView; class CccTestWebView : public QWidget { Q_OBJECT public: explicit CccTestWebView(QWidget *parent = nullptr); ~CccTestWebView(); void initWidget(); private: //QWebEngineView* m_pWebView = nullptr; CccWebEngineView* m_pWebView = nullptr; }; #endif // CCCTESTWEBVIEW_H
#include "CccTestWebView.h" #include "CccWebEngineView.h" #include#include CccTestWebView::CccTestWebView(QWidget *parent) :QWidget(parent) { initWidget(); } CccTestWebView::~CccTestWebView() { } void CccTestWebView::initWidget() { resize(420,680); auto mainLayout = new QVBoxLayout(this); mainLayout->setSpacing(0); mainLayout->setMargin(0); //m_pWebView = new QWebEngineView(this); m_pWebView = new CccWebEngineView(this);//换成自实现的 m_pWebView->load(QUrl("http://www.baidu.com")); mainLayout->addWidget(m_pWebView); }
这时候就可以点击链接跳到相应的链接的页面去了
3、Qt如何跟JS之间进行互相通信呢?
CccJsContext.h#ifndef CCCJSCONTEXT_H #define CCCJSCONTEXT_H #includeCccJsContext.cpp#include class CccJsContext : public QObject { Q_OBJECT Q_PROPERTY(QString userId READ getUserId WRITE setUserId NOTIFY sigUserIdChange) Q_PROPERTY(QString userToken READ getUserToken WRITE setUserToken NOTIFY sigUserTokenChange) Q_PROPERTY(QString userInfo READ getUserInfo WRITE setUserInfo NOTIFY sigUserInfoChange) public: explicit CccJsContext(QObject *parent = nullptr); void createConnections(); void setUserId(const QString& paramUserId); QString getUserId()const; void setUserToken(const QString& paramUserToken); QString getUserToken()const; void setUserInfo(const QString& paramUserInfo); QString getUserInfo()const; signals: void sigUserIdChange(); void sigUserTokenChange(); void sigUserInfoChange(); public: void sendMsg(QWebEnginePage* page, const QString& msg); private: QString userId = "123456"; QString userToken = "e9eo98kkkjj"; QString userInfo = "this is a test"; }; #endif // CccJsContext
#include "CccJsContext.h" #includeCccTestWebView.h CccTestWebView.cpp修改#include #include #include #include CccJsContext::CccJsContext(QObject *parent) :QObject(parent) { createConnections(); } void CccJsContext::createConnections() { } void CccJsContext::sendMsg(QWebEnginePage *page, const QString &msg) { page->runJavaScript(msg,[](const QVariant& v) { Q_UNUSED(v); }); } void CccJsContext::setUserId(const QString ¶mUserId) { userId = paramUserId; emit sigUserIdChange(); } QString CccJsContext::getUserId() const { return userId; } void CccJsContext::setUserToken(const QString& paramUserToken) { userToken = paramUserToken; emit sigUserTokenChange(); } QString CccJsContext::getUserToken()const { return userToken; } void CccJsContext::setUserInfo(const QString& paramUserInfo) { userInfo = paramUserInfo; emit sigUserInfoChange(); } QString CccJsContext::getUserInfo()const { return userInfo; }
#ifndef CCCTESTWEBVIEW_H #define CCCTESTWEBVIEW_H #includeclass CccWebEngineView; class QWebChannel; class CccJsContext; class CccTestWebView : public QWidget { Q_OBJECT public: explicit CccTestWebView(QWidget *parent = nullptr); ~CccTestWebView(); void initWidget(); private: //QWebEngineView* m_pWebView = nullptr; CccWebEngineView* m_pWebView = nullptr; QWebChannel* m_pWebChannel = nullptr; CccJsContext* m_pJsContext = nullptr; }; #endif // CCCTESTWEBVIEW_H
#include "CccTestWebView.h" #include "CccWebEngineView.h" #include "CccJsContext.h" #include#include #include CccTestWebView::CccTestWebView(QWidget *parent) :QWidget(parent) { initWidget(); } CccTestWebView::~CccTestWebView() { } void CccTestWebView::initWidget() { resize(420,680); auto mainLayout = new QVBoxLayout(this); mainLayout->setSpacing(0); mainLayout->setMargin(0); //m_pWebView = new QWebEngineView(this); m_pWebView = new CccWebEngineView(this); m_pWebChannel = new QWebChannel(this); m_pJsContext = new CccJsContext(this); m_pWebChannel->registerObject("CccJsBridge", m_pJsContext); m_pWebView->page()->setWebChannel(m_pWebChannel); QString htmlPath = "file:///"; htmlPath.append("/Users/myname/Desktop/htmltest/test.html"); m_pWebView->load(QUrl(htmlPath)); //Qt调用js函数例子 //QString jsFun = "QtCallJsFun()"; //m_pJsContext->sendMsg(m_pWebView->page(),jsFun); mainLayout->addWidget(m_pWebView); }
结果
test.html在这个Demo里面JS是通过同步的方式获取C++中CccJsBridge中的值的,也可以通过在CccJsContext加上槽函数给JS调用
qwebchannel.js 在Qt安装目录下搜索找下
msgutls.js代码为
var CccJsBridge;
function init()
{
if (typeof qt != 'undefined')
{
new QWebChannel(qt.webChannelTransport, function(channel)
{
CccJsBridge = channel.objects.CccJsBridge;
}
);
}
else
{
alert("qt对象获取失败!");
}
}
// 向qt发送消息
function sendMessage(msg)
{
if(typeof CccJsBridge == 'undefined')
{
alert("context对象获取失败!");
}
else
{
CccJsBridge.onMsg(msg);
}
}
// 控件控制函数
function onBtnSendMsg()
{
var cmd = document.getElementById("待发送消息").value;
sendMessage(cmd);
}
function recvMessage(msg)
{
alert("接收到Qt消息:" + msg);
}
init();



