Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QtWebEngine
  4. Replace QWebKit Object.signal.connect()
Forum Updated to NodeBB v4.3 + New Features

Replace QWebKit Object.signal.connect()

Scheduled Pinned Locked Moved Solved QtWebEngine
14 Posts 4 Posters 4.4k Views 3 Watching
  • 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.
  • M Offline
    M Offline
    maximus
    wrote on 13 Sept 2016, 02:54 last edited by
    #1

    In QWebKit, we could bind a signal of a C++ object to a JS method with this method:

    function connectSlots() {
            if ( !connected ) {
                connected = true;
                MainWindow.signal_sensorFound.connect(this, foundSensor);
            }
    }
    

    This no longer exist in QWebEngine, this code would automatically convert the method argument of foundSensor to JS type arguments.
    I am trying to find an alternative with QWebEngine. I haven't found this specified in the documentation of Qt to migrate to QWebEngine.

    If I tried to use runJavascript and call my JS method directly, the Qt type arguments are not converted like before
    Example:

    emit signal_sensorFound(deviceType, this->lstDevicePaired.size(), this->lstDevicePaired, this->lstTypeDevicePaired, fromStudioPage); //old method with QWebKit, connect the signal to a JS method with the same number of arguments, arguments get converted automatically
    ui->webView_settings->page()->runJavaScript("alertMe();");  //this works, JS method called with success, no arguments
    ui->webView_settings->page()->runJavaScript("foundSensor(deviceType, lstDevicePaired.size(), lstDevicePaired, lstTypeDevicePaired, fromStudioPage);");  //this does not work..
    

    Free Indoor Cycling Software - https://maximumtrainer.com

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 13 Sept 2016, 07:25 last edited by
      #2

      Hi,

      Not a direct answer but you might be interested by @Konstantin-Tokarev QtWebKit reboot.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      M 1 Reply Last reply 15 Oct 2016, 18:42
      0
      • C Offline
        C Offline
        Chris Kawa
        Lifetime Qt Champion
        wrote on 13 Sept 2016, 10:26 last edited by Chris Kawa
        #3

        The problem with this

        ui->webView_settings->page()->runJavaScript("foundSensor(deviceType, lstDevicePaired.size(), lstDevicePaired, lstTypeDevicePaired, fromStudioPage);");
        

        is that you're just evaluating a string. deviceType and the rest are just symbols that javascript doesn't know. It's like you'd write the same in the page itself without declaring these variables.
        since you're just evaluating a string you need to resolve the values of these c++ variables yourself. For example if you have a js function

        function foo(an_int, a_string) { ... }
        

        you can pass an int and a string from c++ like this:

        int bar = 42;
        QString bazz("hello");
        QString script("foo(%1,'%2');");
        page->runJavaScript(script.arg(QString::number(bar), bazz));
        
        1 Reply Last reply
        1
        • M Offline
          M Offline
          maximus
          wrote on 15 Sept 2016, 22:17 last edited by
          #4

          Thanks both for your answers!

          2 good solutions, I am not moved to QWebEngine yet, but I will probably do it.
          Everything seems to work in QWebEngine now with a few code modification.

          Merci!


          Free Indoor Cycling Software - https://maximumtrainer.com

          1 Reply Last reply
          0
          • M Offline
            M Offline
            maximus
            wrote on 15 Sept 2016, 23:33 last edited by
            #5
            QString script("foundSensor(%1, %2, %3, %4, %5);");
            ui->webView_settings->page()->runJavaScript(script.arg(deviceType, lstDevicePaired.size(), lstDevicePaired, lstTypeDevicePaired, fromStudioPage));
            

            trying to transfer (int, int, lst<int>, lst<int>, boolean)
            const': cannot convert argument 3 from 'QList<int>' to 'char'


            Free Indoor Cycling Software - https://maximumtrainer.com

            1 Reply Last reply
            0
            • C Offline
              C Offline
              Chris Kawa
              Lifetime Qt Champion
              wrote on 16 Sept 2016, 20:16 last edited by Chris Kawa
              #6

              You misunderstood. It's not enough to pass the variables through arg(). It's not a magic function that translates types to javascript compatible strings. You need to build these strings yourself.

              I don't know what types you use but lets say for the sake of example that they are something like this:

              int deviceType = 42;
              QList<int> lstDevicePaired = { 42, 43, 44 };
              

              To make this work in javascript you need to construct a string like this:

              "foundSensor(42, [42,43,44]);"
              

              So you can do it like this for example:

              QStringList temp;
              std::transform(lstDevicePaired.begin(), lstDevicePaired.end(), std::back_inserter(temp), [](int i){ return QString::number(i); });
              
              QString script("foundSensor(%1, [%2]);");
              QString arg1= QString::number(deviceType);
              QString arg2 = temp.join(',');
              
              ui->webView_settings->page()->runJavaScript(script.arg(arg1, arg2));
              

              Same goes of course for the other parameters. I just used first two to give you example.

              M 1 Reply Last reply 15 Jan 2017, 03:10
              0
              • S SGaist
                13 Sept 2016, 07:25

                Hi,

                Not a direct answer but you might be interested by @Konstantin-Tokarev QtWebKit reboot.

                M Offline
                M Offline
                maximus
                wrote on 15 Oct 2016, 18:42 last edited by
                #7

                @SGaist said in Replace QWebKit Object.signal.connect():

                Hi,

                Not a direct answer but you might be interested by @Konstantin-Tokarev QtWebKit reboot.

                Hey SGaist,

                Any idea if QWebKit will be part of a future Qt release, like 6.0? I may just wait for that instead :) Could help on the project also.
                Cheers,
                Max


                Free Indoor Cycling Software - https://maximumtrainer.com

                K 1 Reply Last reply 15 Oct 2016, 21:30
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 15 Oct 2016, 18:54 last edited by
                  #8

                  Do you mean the reboot ? No, I don't.

                  Waiting for Qt 6 might not be the best choice, it won't get started before at least two years.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • M maximus
                    15 Oct 2016, 18:42

                    @SGaist said in Replace QWebKit Object.signal.connect():

                    Hi,

                    Not a direct answer but you might be interested by @Konstantin-Tokarev QtWebKit reboot.

                    Hey SGaist,

                    Any idea if QWebKit will be part of a future Qt release, like 6.0? I may just wait for that instead :) Could help on the project also.
                    Cheers,
                    Max

                    K Offline
                    K Offline
                    Konstantin Tokarev
                    wrote on 15 Oct 2016, 21:30 last edited by
                    #9

                    @maximus We have ready to use binary packages compatible with Qt 5.7, and we are planning to publish future binary builds as Qt SDK components. Plan is to make proper release from current development branch alongside with Qt 5.8

                    If you are willing to help us, it would be very much welcome!

                    1 Reply Last reply
                    1
                    • C Chris Kawa
                      16 Sept 2016, 20:16

                      You misunderstood. It's not enough to pass the variables through arg(). It's not a magic function that translates types to javascript compatible strings. You need to build these strings yourself.

                      I don't know what types you use but lets say for the sake of example that they are something like this:

                      int deviceType = 42;
                      QList<int> lstDevicePaired = { 42, 43, 44 };
                      

                      To make this work in javascript you need to construct a string like this:

                      "foundSensor(42, [42,43,44]);"
                      

                      So you can do it like this for example:

                      QStringList temp;
                      std::transform(lstDevicePaired.begin(), lstDevicePaired.end(), std::back_inserter(temp), [](int i){ return QString::number(i); });
                      
                      QString script("foundSensor(%1, [%2]);");
                      QString arg1= QString::number(deviceType);
                      QString arg2 = temp.join(',');
                      
                      ui->webView_settings->page()->runJavaScript(script.arg(arg1, arg2));
                      

                      Same goes of course for the other parameters. I just used first two to give you example.

                      M Offline
                      M Offline
                      maximus
                      wrote on 15 Jan 2017, 03:10 last edited by
                      #10

                      @Chris-Kawa said in Replace QWebKit Object.signal.connect():

                      You misunderstood. It's not enough to pass the variables through arg(). It's not a magic function that translates types to javascript compatible strings. You need to build these strings yourself.

                      Sorry for the old bump, just got back working on this.
                      Thanks Chris for the example, I think I am constructing the JS argument fine now, the problem is that the JS function is not recognized.
                      I went back to a simple example to show the problem.

                      Here is the code I'm using. Now I don't have any problem from my JS to call a Qt function, the problem I'm having is calling a JS function from Qt code.

                      QString jsToRun2 = "sayHello()";
                      ui->webView_settings->page()->runJavaScript(jsToRun2);
                      

                      JS code in the html page that I control:

                      function sayHello() {alert('hello');}
                      

                      Getting this error in the Qt console : js: Uncaught ReferenceError: sayHello is not defined


                      Free Indoor Cycling Software - https://maximumtrainer.com

                      1 Reply Last reply
                      0
                      • C Offline
                        C Offline
                        Chris Kawa
                        Lifetime Qt Champion
                        wrote on 15 Jan 2017, 11:03 last edited by
                        #11

                        Is the page already loaded when you call this? Try this:

                        connect(ui->webView_settings->page(), &QWebEnginePage::loadFinished, [&]{
                            QString jsToRun2 = "sayHello()";
                            ui->webView_settings->page()->runJavaScript(jsToRun2);
                        });
                        
                        1 Reply Last reply
                        0
                        • M Offline
                          M Offline
                          maximus
                          wrote on 15 Jan 2017, 13:47 last edited by maximus
                          #12

                          Hey Chris,

                          Yes the page was loaded. even then it seems it could not find the function. I can modify elements with jquery but not call the function.

                          I changed the location of the function and it worked for some reason. I guess you can't access function when they are in document.ready part of the js

                          $(function() { //loaded on dom ready, not accessible by Qt runJavascript
                              function sayhello() {
                                 alert('say hello');
                              }
                          }
                          

                          Changed to :

                              function sayhello() {
                                alert('say hello'); //working here!
                              }
                              $(function() { /
                               //other method not being call by Qt
                              }
                          

                          Thanks for helping me figure it out.
                          Fixed by moving all the function outside of the document.ready ( $(function() { )


                          Free Indoor Cycling Software - https://maximumtrainer.com

                          1 Reply Last reply
                          0
                          • C Offline
                            C Offline
                            Chris Kawa
                            Lifetime Qt Champion
                            wrote on 16 Jan 2017, 05:53 last edited by
                            #13

                            I'm no javascript expert, but the function in your first example seems to be a local function (local to the scope of the callback), so yeah, you can't access it from a global scope. When you moved it out to the global scope it's accessible.

                            1 Reply Last reply
                            1
                            • M Offline
                              M Offline
                              maximus
                              wrote on 16 Jan 2017, 23:27 last edited by
                              #14

                              Exactly that, Thanks Chris !


                              Free Indoor Cycling Software - https://maximumtrainer.com

                              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