Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt WebKit
  4. Calling JS from a loop in C++ and keeping it responsive
QtWS25 Last Chance

Calling JS from a loop in C++ and keeping it responsive

Scheduled Pinned Locked Moved Unsolved Qt WebKit
bridgeasynchronousjavascriptqtwebkit
7 Posts 3 Posters 3.6k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    jramm
    wrote on last edited by
    #1

    I'm using Qt Webkit to show a map (with leaflet.js). When a JS event happens (a certain button is clicked), I call some C++ code (by directly calling a function in a C++ object that has been added to the JS environment).
    This code runs a loop and on each iteration fires two signals. One signal provides the location of a marker and the other signal provides a percentage update.

    This invokes some javascript code which creates a marker and should print out the percentage to the console. However, the console.log calls are queued until the end of the loop and only then processed. How can I make this happen async?

    javascript code:

     MT.Progress = function(){
        BRIDGE.progressUpdated.connect(this.update.bind(this)); //BRIDGE is the C++ object that has been added to the javascript window
     }
    
     MT.Progress.prototype.update = function(perc){
       console.log(perc);
     }
    
     MT.Markers = function(){
    
        var pb = new MT.Progress();
        BRIDGE.markerUpdated.connect(this.addMarker.bind(this));
    
        // Call code to loop through markers
        BRIDGE.getMarkers(); 
     }
    
     MT.Markers.prototype.addMarker = function(){
       var marker = new PruneCluster.Marker(lat, lon);
       this.clusterLayer.RegisterMarker(marker);
     }
    

    C++ function:

    void Bridge::getMarkers()
    {
        QSqlQuery query(db);
        query.prepare("SELECT lat, lon FROM locations");
        query.exec();
    
        int size = query.size();
        if (size > 0) 
        {
          int increment = 0.01 * size;
          int percent = 0;
          int countdown = increment;
    
          while(query.next()){
            countdown--;
            if (countdown==0)
            {
              percent++;
              emit progressUpdated(percent);
              countdown = increment;
            }
            double lat = query.value(1).toDouble();
            double lng = query.value(2).toDouble();
            emit markerUpdated(lat, lng);
          
          }
          emit updatesFinished();
        }
        
    
    }
    
    1 Reply Last reply
    0
    • L Offline
      L Offline
      Leonardo
      wrote on last edited by
      #2

      Hi. The correct solution would be to use threads, but you can try adding

      QCoreApplication::processEvents();
      

      http://doc.qt.io/qt-5/qcoreapplication.html#processEvents

      to your loop and see whether it gives some satisfying performance.

      J 1 Reply Last reply
      0
      • L Leonardo

        Hi. The correct solution would be to use threads, but you can try adding

        QCoreApplication::processEvents();
        

        http://doc.qt.io/qt-5/qcoreapplication.html#processEvents

        to your loop and see whether it gives some satisfying performance.

        J Offline
        J Offline
        jramm
        wrote on last edited by
        #3

        @Leonardo
        Thanks for the reply.
        I had moved the Bridge class to a separate thread with no luck - but I suspect that because the JS is calling the functions directly (using Q_INVOKABLE) they are not being executed in separate thread.

        Would the answer be to move all logic out of the Bridgeclass and simply use that class to pass signals along (from javascript to the logic class and back again?). It feels a bit clunky to have a class that just regurgitates signals; would it affect performance?

        1 Reply Last reply
        0
        • L Offline
          L Offline
          Leonardo
          wrote on last edited by
          #4

          Hi. You're right. You should use signals. When you call the method directly, it blocks the UI's thread. You need to keep it free to perform the rendering. Take a look at this sample:

          http://doc.qt.io/qt-5/qthread.html#details

          You should do something like that.

          1 Reply Last reply
          0
          • J Offline
            J Offline
            jramm
            wrote on last edited by
            #5

            As far as I can see, there is no way for the JS to send a signal, so it seems as though I will need this intemediary message passer class? JS calls the method on this class directly which sends a signal...

            I wonder if using the newer QWebEngine provides a more elegant solution around this?

            T 1 Reply Last reply
            0
            • J jramm

              As far as I can see, there is no way for the JS to send a signal, so it seems as though I will need this intemediary message passer class? JS calls the method on this class directly which sends a signal...

              I wonder if using the newer QWebEngine provides a more elegant solution around this?

              T Offline
              T Offline
              t3685
              wrote on last edited by
              #6

              @jramm

              Would the http://doc.qt.io/qt-5/qml-workerscript.html WorkerScript element help you with your problem?

              1 Reply Last reply
              0
              • L Offline
                L Offline
                Leonardo
                wrote on last edited by
                #7

                @jramm, signals are methods. You can declare a signal as Q_INVOKABLE and call it from JS.

                1 Reply Last reply
                0

                • Login

                • Login or register to search.
                • First post
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved