Qt中對js和HTML通訊的理解

大富吖發表於2020-12-03

一、背景

在Qt5.6以下版本,Qt還沒有刪除QWebKits元件,Qt5.6以上版本,刪除了QWebKits元件,升級為QWebEngine元件。
基於QWebEngine,引入QWebChannel通訊機制,GPS定位系統互動驅動百度地圖已經完全適配QWebEngine元件。

二、原理闡述

在這裡插入圖片描述
QWebEngine提供了呼叫HTML裡面JavaScript的方法,這裡HTML像是一個介面,在HTML尾部有一個這樣的標籤, ,在這個標籤內的函式和變數體中寫入一些函式和變數,這些函式和變數要麼是JavaScript中的呼叫,要麼是Qt中的呼叫,所以,HTML像是一個QT和網頁的橋樑。

三、WebChannel的使用

QWebChannel要注意兩個方面:第一,Qt方面,需要包含QWebChannel類,註冊好QWebChannel需要連線的Qt的物件;第二,JS方面,官方提供了配套的qwebchannel.js檔案,這個js檔案就相當於駐JavaScript負責通訊的。

1.JS檔案

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>地圖演示</title>
<script src="js/qwebchannel.js"></script>                                <!--> !!!!!!重點1<-->
<script src="js/apiv1.3.min.js"></script>                           
<!--script type="text/javascript" src="http://api.map.baidu.com/api?v=1.3"></script-->
<link rel="stylesheet" type="text/css" href="bmap.css"/>
</head>
<body>
<div style="left:0;top:0;width:100%;height:100%;position:absolute;" id="container"></div>
</body>
</html>

<script>

var mapOptions={
                minZoom: 3,
                maxZoom:19,
                mapType:  BMAP_NORMAL_MAP
              }
var map = new BMap.Map("container",mapOptions);      // 設定街道圖為底圖
var point = new BMap.Point(116.468278, 39.922965);   // 建立點座標
map.centerAndZoom(point,14);                         // 初始化地圖,設定中心點座標和地圖級別。

map.addControl(new BMap.NavigationControl({offset: new BMap.Size(10, 90)}));
map.enableScrollWheelZoom();                  // 啟用滾輪放大縮小。
map.enableKeyboard();                         // 啟用鍵盤操作。
map.enableContinuousZoom();                   // 啟用連續縮放
var myIcon = new BMap.Icon("images/Point.png", new BMap.Size(20,25));
var marker = new BMap.Marker(point,{icon:myIcon});   // 建立標註
map.addOverlay(marker);                              // 載入標註

// !!!!重點2!!!
new QWebChannel(qt.webChannelTransport,
    function(channel){
        window.bridge = channel.objects.person; // 註冊
    }
);

var dragFlag=false;

// !!!!重點3!!!
var updateInfo = function(lng,lat)
{
    window.bridge.getCoordinates(lng,lat);
}

function showAddress(longjitude,latitude)
{
   var gpsPoint = new BMap.Point(longjitude, latitude);

   if(!dragFlag)
   {
     map.panTo(gpsPoint);
   }
   marker.setPosition(gpsPoint);
}

function showStreetMap()
{
   map.setMapType(BMAP_NORMAL_MAP);
};

function showSatelliteMap()
{
   map.setMapType(BMAP_SATELLITE_MAP);
}
// !!!!!重點4!!!
map.addEventListener("mousemove",function(e) {      

    updateInfo(e.point.lng,e.point.lat);

});

map.addEventListener("dragstart",function(e){
   dragFlag=true;

});

map.addEventListener("dragend",function(e){
   dragFlag=false;
});

map.addEventListener("zoomend",function(e){

});


</script>

2.C++方面處理

    // 準備Javascript檔案互動
    QString strMapPath = "qrc:/map/map.html";                   // 設定地圖路徑

    QWebEnginePage *page = new QWebEnginePage(this);            // 定義QWebEnginePage介面負責開啟html檔案
    QWebChannel *channel = new QWebChannel(this);               // 定義QWebChannel負責

    channel->registerObject(QString("person"),this);            //  QWebChannel對Widget類,註冊一個person的通訊介質 /
                                                                //  在js檔案中person負責成為window.bridge /
                                                                //  在this中也就是Widget類註冊channel,channel訪問的位Widget下的槽函式。
    page->load(strMapPath);                                     //  webenginePage載入html地圖。
    page->setWebChannel(channel);                               //  webenginePage載入Channel功能
    ui->webEngine->setPage(page);                               //  ui顯示該page。

下面是槽函式

public slots:

    void getCoordinates(QString lon, QString lat) {

            QString tempLon="Mouse Lontitude:"+lon+"°";
            QString tempLat="Mouse Lattitude:"+lat+"°";
            ui->label_mouse_altitude->setText(tempLat);
            ui->label_mouse_latitude->setText(tempLon);

    };

相關文章