QML WebEngineView 和 js 交互

QML WebEngine,WebChannel简单使用。

参见项目示例
github
gitee

QWebEngineView C++和js交互思路类似,但是代码更简洁,纯QML/js代码,无需使用C++/python代码

0. WebEngineView

直接加载网页,无交互

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

import QtQuick 2.15
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.15
import QtWebEngine 1.3

Item {
WebEngineView {
width:1000;
anchors.centerIn: parent
id:webview
anchors.fill: parent
url: "charts.html"
}
}

需要在当前路径放入html和js文件以及Qtqwebchannel.js

1.HTML的js调用QML/js

HTMLjs调用QML/js需要借助WebChannel

QML代码改为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30

import QtQuick 2.15
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.15
import QtWebEngine 1.3
import QtWebChannel 1.0

Item {
QtObject {//注意3.1
id: webObject
WebChannel.id: "webObject" //注意3.2
function pageLoadFinished(){ //注意3.3
//todo
}
}

WebChannel {
id: channel
registeredObjects: [webObject] //注意2
}

WebEngineView {
width:1000;
anchors.centerIn: parent
id:webview
anchors.fill: parent
url: "charts.html"
webChannel: channel //注意1
}
}

整体分为三个步骤

  1. 通过WebEngineView.webChannel设置WebChannel

  2. 通过WebChannel.registeredObjects注册对象。

  3. 实现注册对象。

    • 通过2注册的对象需为QtObject对象。
    • QtObject.WebChannel.id字符串对应js中的对象名
    • pageLoadFinished()函数名需与js中对应

html/js代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8" />
<title></title>
<script src="qwebchannel.js"></script>
<script>
new QWebChannel(qt.webChannelTransport,
function (channel) {
var webObject = channel.objects.webObject; //注意1
window.webObject = webObject;
window.webObject.pageLoadFinished(); //注意2
});
</script>
</head>

<body>
<div id="today" style="width: 1600px;height:500px;"></div>
<div id="total" style="width: 1600px;height:500px;"></div>
</body>
</html>

  1. 注意1中channel.objects.webObject中的对象名webObject需与QtObject.WebChannel.id字符串相同
  2. 注意2中pageLoadFinished()函数名需与QtObject类中的槽函数名称相同

2.QML/js调用HTML的js

QML代码改为

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29

import QtQuick 2.15
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.15
import QtWebEngine 1.3
import QtWebChannel 1.0

Item {
QtObject {
id: webObject
WebChannel.id: "webObject"
signal setData(string todayData, string totalData, string updateTime);//注意
}

WebChannel {
id: channel
registeredObjects: [webObject]
}

WebEngineView {
width:1000;
anchors.centerIn: parent
id:webview
anchors.fill: parent
url: "charts.html"
webChannel: channel
}
}

整体也是分为三个步骤。不同之处在于声明信号setData,, 信号名需与js中对应,并在合适的时机发射

html/js代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8" />
<title></title>
<script src="qwebchannel.js"></script>
<script>
var updateData = function (todayData, totalData, updateTime) {
//todo
}

new QWebChannel(qt.webChannelTransport,
function (channel) {
var webObject = channel.objects.webObject; //注意1
window.webObject = webObject;
window.webObject.setData.connect(updateData); //注意2
});
</script>
</head>

<body>
<div id="today" style="width: 1600px;height:500px;"></div>
<div id="total" style="width: 1600px;height:500px;"></div>
</body>
</html>

  1. 注意1中channel.objects.webObject中的对象名webObject需与QtObject.WebChannel.id字符串相同
  2. 注意2中window.webObject.setData函数名需与QtObject类中的信号名称相同