[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_OBJECTpublic:
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().
-