Search code examples
javascriptc++qtgoogle-mapsqtwebkit

Reading the return value of a java script function with "evaluateJavaScript" from Qt


This is my route planner widget implemented with Qt5 and WebKit

How to get a JavaScript function return value in C++?

After a long time of not using JavaScript, I implemented a route planner with the Google maps API V3. I defined some functions to access the scripting part of it via Qt's WebKit function: evaluateJavaScript(). Now the hard part is, to get the position data of the markers (see picture, markers are red). In the JavaScript end, I just return an array. How can I read the "latlng"-array in the Qt end?

Illustration - This is what I want simplified:

// JavaScript
function getJSFoo() {
  return foofoo;
}
// C++
void readInQt() {
  // something like this:
  float val = evaluateJavaScript("getJSFoo()");
  // Do stuff
}

Thanks in advance!

This my code, more or less how I use it. At JavaScript's end:

// Add a marker to the map and push to the array.
function addMarker(location) {
  var marker = new google.maps.Marker({
      position: location,
      map: map,
      draggable:true
  });
  
  var LatLng = marker.getPosition();
  var sLatLng = "Latitude:    " + marker.getPosition().lat().toString() + 
                "\nLongitude: " + marker.getPosition().lng().toString();
  marker.setTitle(sLatLng);

  flightMarker.push(marker);
  return flightMarker;
}

function getMarkers() {
  var latlng = []
  for (var i = 0; i < flightMarker.length; i++) {
    latlng.push(flightMarker[i].getPosition() );
  }
  return latlng;
}

At Qt's end:

void sl_submitRoute() {
    getWaypoints();
}

QList<float> getWaypoints() {
    QList<float> lWaypoints;
    // I don't know what I do here :D
    QVariant varMarkers = mView->page()->mainFrame()->evaluateJavaScript(QString("getMarkers();") );
    QList <QVariant> allListObj = varMarkers.toList();
    qDebug() << allListObj;

    return lWaypoints;
}

Solution

  • I found the solution. Easiest way is to convert data into a QStringList and back. Otherwise data type conversion could result in a leak.

    JavaScript

    function getMarkers() {
      var latlng = []
      for (var i = 0; i < flightMarker.length; i++) {
        var sPos = flightMarker[i].getPosition().lat().toString() + ":" + flightMarker[i].getPosition().lng().toString();
        latlng.push(sPos);
      }
      return latlng;
    }
    

    Qt

    // Returns a list of points: Latitude & Longitude
    RouteF getWaypoints() {
        RouteF lWaypoints;
    
        QVariant varMarkers = mView->page()->mainFrame()->evaluateJavaScript(QString("getMarkers();") );
        QList<QVariant> allListObj = varMarkers.toList();
        for(int i = 0; i < allListObj.size(); i++) {
            QStringList lPoint = allListObj.at(i).toString().split(':');
            if(lPoint.size() != 2) {
                qDebug() << "Warning: Waypoint not valid!";
                continue;
            }
    
            double fLat = lPoint.at(0).toDouble();
            double fLon = lPoint.at(1).toDouble();
            PointF waypoint = PointF(fLat, fLon);
            lWaypoints.push_back(waypoint);
            qDebug() << "Added point: " << fLat << ":" << fLon;
        }
    
        return lWaypoints;
    }