本文结构
1、 Qt5中web开发的基本配置,工程搭建
2、 加载HTML文件
3、 Qt界面窗口调用HTML中的JavaScript函数(Qt调用js)
4、 Qt界面窗口获取HTML中Js函数的返回值
5、 Web端消息主动通知到Qt界面(js通知Qt)
6、完整源码路径
基本配置,工程搭建
(1) Qt安装时要安装web开发组件,本案例采用Qt5.9.6 vs2015开发环境
(2) 新建Qt Gui工程要首先勾选以下三个组件
(3) qwebchannel.js文件,安装Qt后在安装文件夹下面可以搜索找到
(4) 本案例代码文件结构
其中Ui文件的简单布局如下:
其中,左侧为QWebEngineView控件,右侧一个调用js函数的按钮,一个获取js返回值的按钮,另一个为操作结果显示的label控件
加载html文件
找到html文件位置,QWebEngineView的load()函数可以加载html文件显示,形式如下:
m_pWebView->load(QUrl("file:///" + htmlPath));
本例中的html文件路径:
https://github.com/lesliefish/Qt/blob/master/Project/WebTest/WebTest/BMap.html
Qt调用HTML中的JavaScript函数
假设html中有js函数如下:
// 添加一个圆形覆盖物
function addCircle()
{
var point = new BMap.Point(116.404, 39.915);
var circle = new BMap.Circle(point, 6000, { strokeColor: "red", strokeWeight: 5, strokeOpacity: 0.3 }); //创建圆
map.addOverlay(circle); //增加圆
}
在Qt桌面端,只需要用一个字符串把js函数名称弄下来就行啦,然后通过执行runJavaScript函数就可以对html操作了,操作方式如下:
QString jsStr = QString("addCircle()");
m_pWebView->page()->runJavaScript(jsStr);
Qt界面窗口获取HTML中Js函数的返回值
只能调它的js函数还不行啊,我想知道它执行完返回给我啥了,那这个时候就需要看看这个runJavaScript函数了:
void runJavaScript(const QString& scriptSource,
const QWebEngineCallback<const QVariant &> &resultCallback);
如上,这个调用是异步的,这个可以传个回调函数进去,执行结果可以直接在回调函数来处理。
在本Demo中直接用lambda函数处理了,如下:
QString WebTest::getJsRetString()
{
QEventLoop loop;
connect(this, &WebTest::signalRunJsOver, &loop, &QEventLoop::quit);
QString jsStr = "getInfo();";// 调用Js的getInfo函数
QString retStr{}; // 返回值
// 通过loop循环等到回调上来数据再继续
m_pWebView->page()->runJavaScript(jsStr, [&](const QVariant &v)
{
retStr = v.toString();
// 在头文件中定义这个函数,收到js的回调返回值后,结束loop循环
emit signalRunJsOver();
});
loop.exec(); // 收不到回调处理结束信号,我就在这里循环等待
return retStr;
}
Web端消息主动通知到Qt界面
以上都是Qt端主动操作web端的对象、函数等,那web端要发某个消息给Qt端,怎么处理呢?
用QWebChannel,基本使用方式如下:
m_pWebChannel = new QWebChannel(this); // 创建对象
// 注册一个qtui对象 html端通过此名称向qt端发送消息
m_pWebChannel->registerObject(QString("qtui"), this);
m_pWebView->page()->setWebChannel(m_pWebChannel);
基本定义完成后,我们需要定义一个槽函数,接收web端发的消息,定义基本格式如下:
public slots: // 一定要这样定义哦,否则会收不到消息
void recieveJsMessage(const QString& jsMsg);
在web端的js端发送消息方式,要按你定义的qtui对象名称操作噢:
new QWebChannel(qt.webChannelTransport, function (channel) {
var qtui = channel.objects.qtui;
qtui.recieveJsMessage("你点我干啥!");
})
注意:html端一定要加载qwebchannel.js文件,路径要正确。
程序跑起来结果:
程序Demo源码地址
https://github.com/lesliefish/Qt/tree/master/Project/WebTest
环境:vs2015+Qt5.9.6,完整源码,可直接运行