[SOLVED] Embedding Google Maps API into QWebView using .html, dataset used in .html is changed during runtime, can't update .html embedded into QWebView.



  • Hello all,

    I'm using Qt5 for compilation. Firstly, my project is about getting a continuous data flow of X and Y coordinates every 1 second from Pvt struct, and displaying them on WebView with google maps using google maps API by updating the map with up to last 15 markers (coordinates) every 1 seconds. However, my google maps doesn't update. The code is as follows,

    My gmaps.h file,

    #ifndef GMAPS_H
    #define GMAPS_H

    #include <QtGui>
    #include <QtCore>
    #include <QtWebKitWidgets/QWebView>
    #include <QtWebKitWidgets/QWebFrame>

    class Maps : public QWidget
    {
    Q_OBJECT

    public:
    Maps(QWidget *parent = 0);
    void setCenter(double xCoor, double yCoor);
    void addMarker(double xCoor, double yCoor);
    void setupUI(QWebView *myView);

    private:
    QWebView *mView;
    QVector<double> latitudeArray;
    QVector<double> longitudeArray;
    };

    #endif // GMAPS_H

    My gmaps.cpp file

    #include "gmaps.h"
    #include <QGridLayout>

    Maps::Maps(QWidget *parent)
    : QWidget(parent)
    {
    }

    void Maps::setupUI(QWebView* myView)
    {

    this->mView = myView;
    mView->settings()->setAttribute( QWebSettings::JavascriptEnabled, true );
    mView->settings()->setObjectCacheCapacities(0,0,0);
    mView->triggerPageAction(QWebPage::ReloadAndBypassCache);
    mView->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true);
    
    mView->page()->mainFrame()->evaluateJavaScript(QString("xCoorArray = []"));
    mView->page()->mainFrame()->evaluateJavaScript(QString("yCoorArray = []"));
    QString fileName = qApp->applicationDirPath() + "/maps.html";
    if( !QFile(fileName).exists() ) {
        qDebug() << "File not found:" << fileName;
    }
    QUrl url = QUrl::fromLocalFile( fileName );
    mView->load( url );
    

    }

    void Maps::setCenter(double xCoor, double yCoor) {

    mView->page()->mainFrame()->evaluateJavaScript(QString("x_init_Coor = %1").arg(xCoor));
    mView->page()->mainFrame()->evaluateJavaScript(QString("y_init_Coor = %1").arg(yCoor));
    

    }

    void Maps::addMarker(double xCoor, double yCoor)
    {

    if ( latitudeArray.size() < 15 && longitudeArray.size() < 15 ) {
    
        latitudeArray.append(xCoor);
        longitudeArray.append(yCoor);
        mView->page()->mainFrame()->evaluateJavaScript(QString("xCoorArray.push(%1)").arg(xCoor));
        mView->page()->mainFrame()->evaluateJavaScript(QString("yCoorArray.push(%1)").arg(yCoor));
    
    }
    else {
        latitudeArray.removeFirst();
        latitudeArray.append(xCoor);
        longitudeArray.removeFirst();
        longitudeArray.append(yCoor);
        mView->page()->mainFrame()->evaluateJavaScript(QString("xCoorArray.shift()"));
        mView->page()->mainFrame()->evaluateJavaScript(QString("xCoorArray.push(%1)").arg(xCoor));
        mView->page()->mainFrame()->evaluateJavaScript(QString("yCoorArray.shift()"));
        mView->page()->mainFrame()->evaluateJavaScript(QString("yCoorArray.push(%1)").arg(yCoor));
    
    }
    

    // QString fileName = qApp->applicationDirPath() + "/maps.html";
    // QUrl url = QUrl::fromLocalFile( fileName );
    // mView->load( url );

    }

    And, the calls to this object are made from another class constructor X where Maps map is a variable like,
    X::X(QWidget *parent) : QDialog(parent), ui(new Ui::X) {
    map.setupUI(ui->webView);
    map.setCenter(49.00, 11.00);
    }

    And this class X is the main GUI, in which a function called newPvt is called every second with fresh data set as,

    void X::newPvt(const struct Pvt &pvt) {

    map.addMarker(pvt.posLat, pvt.posLon);
    //ui->webView->page()->settings()->clearMemoryCaches();
    //ui->webView->reload();
    

    // ui->webView->repaint();
    //ui->webView->update();

    }
    The maps.html is,

      var map;
      var markers;
      
      function initialize() {
        var myOptions = {
          zoom: 8,
          center: new google.maps.LatLng(x_init_Coor, y_init_Coor),
          mapTypeId: google.maps.MapTypeId.HYBRID,
          zoomControl: true,
          zoomControlOptions: { style: google.maps.ZoomControlStyle.SMALL },
        };
        
        map = new google.maps.Map(document.getElementById('map_canvas'), myOptions);
        setMarkers();
        //document.getElementById('reloadMarkers').addEventListener('click', reloadMarkers);    
      }
      
      function setMarkers(){
        for (var i = 0; i < xCoorArray.length; i++) {
          var latLng = new google.maps.LatLng(xCoorArray[i],yCoorArray[i]);
          var marker = new google.maps.Marker({
            position: latLng,
            map: map,
            animation: google.maps.Animation.DROP
          });
          //markers.push(marker);
        } 
    
      } 
    
      function reloadMarkers(){
        var i;
        for( i = 0; i < markers.length; i++ ){
          markers[i].setMap(NULL);
        }
        markers = [];
        setMarkers();
      }      
    
      google.maps.event.addDomListener(window, 'load', initialize);
    

    // google.maps.event.trigger(map, 'resize');

    All the commented lines above, are the solutions i tried, and which all failed. And, as a note, when i tried reload() and load(url) in addMarker function, they both caused the WebView to go blank.

    So all in all, the solutions i tried are,

    • loading the .html again from the directory in addMarker method.

    • reload(), repaint(), update() in the newPvt function which is instantiated every 1 second.

    • mView->settings()->setObjectCacheCapacities(0,0,0);
      mView->triggerPageAction(QWebPage::ReloadAndBypassCache);
      mView->settings()->setAttribute(QWebSettings::LocalStorageEnabled, true);
      added in setupUI().

    • Trying to create an event in .html for google maps to refresh the markers by itself.

    I'm out of options now. Hope somebody can help. Thanks for reading.

    It's solved, i added another evaluateJavascript command to seperately call setMarker().



Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.