[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.


  • Moderators

    @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=0

    Seems 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"]);

  • Moderators

    @maximus Well either that or since you are parsing it in JS you use JSON parser too. QWebView supports it. Here's an example to parse Json Array.


Log in to reply
 

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