一、本文结构
- Qt5 中 web 开发的基本配置,工程搭建。
- 加载 HTML 文件。
- Qt 界面窗口调用 HTML 中的 JavaScript 函数(Qt 调用 js)
- Qt 界面窗口获取 HTML 中 Js 函数的返回值。
- Web 端消息主动通知到 Qt 界面(js 通知 Qt)。
二、基本配置,工程搭建
(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));
四、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,完整源码,可直接运行。
装载于:https://blog.csdn.net/y396397735/article/details/84707031
(SAW:Game Over!)