[SOLVED] QWebKit Bridge - emiting a custom QList<Object> to a json array?
-
I have a custom QWidget that can emit a QList<Trackpoint> to my QWebView when a file is loaded.
The problem I have is that I'm not able to reconstruct the QList in the javascript slot. I would like to reconstruct a json array somehow.
I have tried with a QList<int> instead and it can reach my javascript code, but unable to do it with my custom Object.A Trackpoint is just a custom Object with 3 fields:
double lon; double lat; double elevation;
C++ Signal - void trackChanged(QList<Trackpoint>);
void GoogleMapWidget::on_loadCourse_clicked() { QString file = QFileDialog::getOpenFileName(this, tr("Import Course"), "C:/Dropbox/VeloTest", tr("Course Files(*.gpx *.tcx *.kml)")); if (file.isEmpty()) return; GpxParser gpxParser; gpxParser.parseFile(file); emit trackChanged(gpxParser.getLstTrackpoints()); }
Javascript slot
$(function() { var connected = false; function connectSlots() { if ( !connected ) { connected = true; googleMapWidget.trackChanged.connect(this, sayHello); } } connectSlots(); //----------------------- function sayHello(coords) { alert(coords[0]); //the QList<Object> doesnt seem to get converted here, QList<int> works.. } });
-
Another solution would be to parse the file in Javascript, but I already coded the function in C++ (QXmlReader..).
I also need to have access to the list of TrackPoint in the C++ code so i'd prefer to learn to how transport the data to the javascript layer correctly.Example of use case:
https://www.dropbox.com/s/6pks6znbusjlctp/exampleMap.png?dl=0
1- User click "load course"
2- Course is parsed and shown in google map
...Thanks
-
Anyone knows the best type of QList<?> I could use so that the QList get transformed to a json array automatically? is that even possible? My object is just 3 double.
-
@maximus I'm not aware of any direct way to convert QList to JSON. Instead I used the following way to convert QList to QJsonArray in one of my projects. I have adjusted it
QJsonObject obj; QJsonArray trackpoints; foreach(Trackpoint* point,list) { QJsonObject obj; obj["lon"] = QString::number(point->getLon()); //add these methods in Trackpoint class obj["lat"] = QString::number(point->getLat()); obj["elevation"] = QString::number(point->getElevation()); trackpoints.append(obj); } obj["TrackPoints"] = trackpoints; QByteArray b = QJsonDocument(obj).toJson(QJsonDocument::Indented);
Then once you get this JSON in the form of bytearray you can send it in the signal and parse it on JavaScript side.
-
Thanks @p3c0
I almost got it with your code. I just need to reparse the QbyteArray to a json array on the client side (javascript).
Still looking for a good way to do that
Here is what I have now :
https://www.dropbox.com/s/doc2zwu030f8e0g/alertMsg1.png?dl=0Seems it is being sent as a "Uint8ClampedArray", but I have negative double in my data, so I should probably change this somehow..
Client slot
function sayHello(coords) { alert(coords + " length is:" + coords.length); //TODO: to parse this back to JsonArray }
Qt
//Convert QList<Trackpoint> to QJsonArray QJsonObject obj; QJsonArray trackpoints; foreach(Trackpoint tp, gpxParser.getLstTrackpoints()) { QJsonObject obj; obj["lon"] = QString::number(tp.getLon(), 'f', 8); //specify decimal for double? obj["lat"] = QString::number(tp.getLat()); obj["elevation"] = QString::number(tp.getElevation()); trackpoints.append(obj); } obj["TrackPoints"] = trackpoints; QByteArray b = QJsonDocument(obj).toJson(QJsonDocument::Indented); emit trackChanged(b);
-
Found a solution!
Apparently a QVariantList get transformed automatically to a Json Object, so this way worked for me without needing to parse:
Qt send signal with a QVariantList, get transformed auto
QJsonArray trackpoints; foreach(Trackpoint tp, gpxParser.getLstTrackpoints()) { QJsonObject obj; obj["lon"] = tp.getLon(); obj["lat"] = tp.getLat(); obj["elevation"] = tp.getElevation(); trackpoints.append(obj); } QVariantList variantLst = trackpoints.toVariantList(); emit trackChanged(variantLst);
Client Slot
function sayHello(coords) { alert(coords + " length is:" + coords.length); alert(coords[1]["lon"]);
-