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. QWebChannel - js: Uncaught ReferenceError: qt is not defined
Forum Updated to NodeBB v4.3 + New Features

QWebChannel - js: Uncaught ReferenceError: qt is not defined

Scheduled Pinned Locked Moved Solved QtWebEngine
15 Posts 8 Posters 23.9k Views 1 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 maximus

    I copied the whole content of qwebchannel.js inside my page just before "new QWebChannel..." and I do not get the error on the Qtcreator console, but still qt is undefined (get the alert message on my webpage).

    Also to note that I try to set my channel after the page is loaded, and it get triggered 2 times? I only load the URL once. I read on other forums that reloading the page could stop the channel from working, but I am unable to make it work in the first place.

    ui->webView_workouts->load(QUrl(Environnement::getUrlWorkout()));
    connect(ui->webView_workouts->page(), SIGNAL(loadFinished(bool)), this, SLOT(connectToJs(bool)));
    
    void Main_WorkoutPage::connectToJs(bool result) {
    
        qDebug() << "connectToJs!" << result;
        if (result) {
            QWebChannel *channel = new QWebChannel(ui->webView_workouts->page());
            ui->webView_workouts->page()->setWebChannel(channel);
            channel->registerObject(QString("workoutObject"), this);
        }
    }
    
    raven-worxR Offline
    raven-worxR Offline
    raven-worx
    Moderators
    wrote on last edited by
    #5

    @maximus
    can you show how you include the qwebchannel.js into your page.
    Are you using a custom HTML page? or are you loading a page?

    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
    If you have a question please use the forum so others can benefit from the solution in the future

    1 Reply Last reply
    0
    • M maximus

      I copied the whole content of qwebchannel.js inside my page just before "new QWebChannel..." and I do not get the error on the Qtcreator console, but still qt is undefined (get the alert message on my webpage).

      Also to note that I try to set my channel after the page is loaded, and it get triggered 2 times? I only load the URL once. I read on other forums that reloading the page could stop the channel from working, but I am unable to make it work in the first place.

      ui->webView_workouts->load(QUrl(Environnement::getUrlWorkout()));
      connect(ui->webView_workouts->page(), SIGNAL(loadFinished(bool)), this, SLOT(connectToJs(bool)));
      
      void Main_WorkoutPage::connectToJs(bool result) {
      
          qDebug() << "connectToJs!" << result;
          if (result) {
              QWebChannel *channel = new QWebChannel(ui->webView_workouts->page());
              ui->webView_workouts->page()->setWebChannel(channel);
              channel->registerObject(QString("workoutObject"), this);
          }
      }
      
      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by
      #6

      @maximus
      Here is a way to include the webchannel stuff without worrying anymore:

      QWebEngineProfile* profile = new QWebEngineProfile("MyWebChannelProfile", parent);
      
      QFile webChannelJsFile(":/qtwebchannel/qwebchannel.js");
      if(  !webChannelJsFile.open(QIODevice::ReadOnly) )
      {
            qFatal( QString("Couldn't open qwebchannel.js file: %1").arg(webChannelJsFile.errorString()) );
      }
      else
      {
              QByteArray webChannelJs = webChannelJsFile.readAll();
              webChannelJs.append( 
                       "\n"
                       "new QWebChannel(qt.webChannelTransport, function(channel) {"
                       "     workoutObject = channel.objects.workoutObject;"
                       "});"
              );
      
              QWebEngineScript script;
                  script.setSourceCode(webChannelJs);
                  script.setName("qwebchannel.js");
                  script.setWorldId(QWebEngineScript::MainWorld);
                  script.setInjectionPoint(QWebEngineScript::DocumentCreation);
                  script.setRunsOnSubFrames(false);
              profile->scripts()->insert(script);
          }
      

      Then make sure you create a QWebEnginePage with the profile on your view: new QWebEnginePage(profile,view)

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      1 Reply Last reply
      1
      • M Offline
        M Offline
        maximus
        wrote on last edited by maximus
        #7

        hey @raven-worx, thanks for the reply

        I am using a custom html page that I control.
        The .js file is loaded this way:
        <script type="text/javascript" src="http://localhost/assets/js/qwebchannel.js"></script>
        I then have another <script> section at the end of my page that is creating a QWebChannel
        I can access the page source and click on the link fine to see the js file.

        Also note that I am using Designer to create my QWebEngineView so object is already instantiated in my .cpp

        I'll try loading it your way and post my result soon.
        Thanks


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

        1 Reply Last reply
        0
        • M Offline
          M Offline
          maximus
          wrote on last edited by
          #8

          You are a lifesaver, it worked this way! Now to figure out how to strip and put this code generic because I use around 10 QWebEngineView :)

          QWebEngineProfile *profile = new QWebEngineProfile("MyWebChannelProfile", this);
          
              QFile webChannelJsFile(":/qtwebchannel/qwebchannel.js");
              if(  !webChannelJsFile.open(QIODevice::ReadOnly) ) {
                  qDebug() << QString("Couldn't open qwebchannel.js file: %1").arg(webChannelJsFile.errorString());
              }
              else {
                  qDebug() << "OK webEngineProfile";
                  QByteArray webChannelJs = webChannelJsFile.readAll();
                  webChannelJs.append(
                              "\n"
                              "var workoutobject"
                              "\n"
                              "new QWebChannel(qt.webChannelTransport, function(channel) {"
                              "     workoutobject = channel.objects.workoutobject;"
                              "});"
                              );
          
                  QWebEngineScript script;
                  script.setSourceCode(webChannelJs);
                  script.setName("qwebchannel.js");
                  script.setWorldId(QWebEngineScript::MainWorld);
                  script.setInjectionPoint(QWebEngineScript::DocumentCreation);
                  script.setRunsOnSubFrames(false);
                  profile->scripts()->insert(script);
              }
          
              QWebEnginePage *myPage = new QWebEnginePage(profile, ui->webView_workouts);
              ui->webView_workouts->setPage(myPage);
          
              QWebChannel *channel = new QWebChannel(myPage);
              ui->webView_workouts->page()->setWebChannel(channel);
              channel->registerObject("workoutobject", this);
          
              ui->webView_workouts->load(QUrl(Environnement::getUrlWorkout()));
          

          And now my .js page doesn't have anything related to Qt, really clean result.
          Thanks a lot
          Max


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

          1 Reply Last reply
          0
          • M Offline
            M Offline
            maximus
            wrote on last edited by
            #9

            I am running into problem using profile->scripts()->insert(script);
            There is conflict with multiple scripts that I insert in my shared QWebEngineProfile.
            I use the same QWebEngineProfile on all my webpage in my application in order to keep cookie data, etc.

            So when I insert a new script, it overwrite the last one inserted and screw up my QWebChannel initialization
            Resulting in warning like "js: Uncaught ReferenceError: zoneObject is not defined"
            Trying to find a solution..
            script.setWorldId(QWebEngineScript::MainWorld); maybe set a unique worldID for each page but that doesnt seem to work now


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

            1 Reply Last reply
            0
            • M Offline
              M Offline
              maximus
              wrote on last edited by
              #10

              Solution found, insert the script to the page instead of the profile

              void WorkoutCreator::createWebChannel() {
              
                  QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
              
                  QFile webChannelJsFile(":/qtwebchannel/qwebchannel.js");
                  if(  !webChannelJsFile.open(QIODevice::ReadOnly) ) {
                      qDebug() << QString("Couldn't open qwebchannel.js file: %1").arg(webChannelJsFile.errorString());
                  }
                  else {
                      qDebug() << "OK webEngineProfile";
                      QByteArray webChannelJs = webChannelJsFile.readAll();
                      webChannelJs.append(
                                  "\n"
                                  "var workoutCreator"
                                  "\n"
                                  "new QWebChannel(qt.webChannelTransport, function(channel) {"
                                  "     workoutCreator = channel.objects.workoutCreator;"
                                  "});"
                                  "\n"
                                  "function enableSaveButton(forceOff) {"
                                  "if (forceOff) {$('#btn-save-workout').prop('disabled', true);return;}"
                                  "var nameValue = $('#name-workout').val();"
                                  "var planValue =   $('#plan-workout').val();"
                                  "var creatorValue = $('#creator-workout').val();"
                                  "if (nameValue.length > 0 && creatorValue.length > 0 && planValue.length > 0) {$('#btn-save-workout').prop('disabled', false);}"
                                  "else {$('#btn-save-workout').prop('disabled', true);}"
                                  "}"
                                  );
              
                      QWebEngineScript script;
                      script.setSourceCode(webChannelJs);
                      script.setName("qwebchannel.js");
                      script.setWorldId(QWebEngineScript::MainWorld);
                      script.setInjectionPoint(QWebEngineScript::DocumentCreation);
                      script.setRunsOnSubFrames(false);
                      //        profile->scripts()->insert(script);
              
                      QWebEnginePage *myPage = new QWebEnginePage(profile, ui->webView_createWorkout);
                      ui->webView_createWorkout->setPage(myPage);
                      myPage->scripts().insert(script);
              
                      QWebChannel *channel = new QWebChannel(myPage);
                      ui->webView_createWorkout->page()->setWebChannel(channel);
                      channel->registerObject("workoutCreator", this);
                  }
              }
              

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

              M 1 Reply Last reply
              0
              • M maximus

                Solution found, insert the script to the page instead of the profile

                void WorkoutCreator::createWebChannel() {
                
                    QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
                
                    QFile webChannelJsFile(":/qtwebchannel/qwebchannel.js");
                    if(  !webChannelJsFile.open(QIODevice::ReadOnly) ) {
                        qDebug() << QString("Couldn't open qwebchannel.js file: %1").arg(webChannelJsFile.errorString());
                    }
                    else {
                        qDebug() << "OK webEngineProfile";
                        QByteArray webChannelJs = webChannelJsFile.readAll();
                        webChannelJs.append(
                                    "\n"
                                    "var workoutCreator"
                                    "\n"
                                    "new QWebChannel(qt.webChannelTransport, function(channel) {"
                                    "     workoutCreator = channel.objects.workoutCreator;"
                                    "});"
                                    "\n"
                                    "function enableSaveButton(forceOff) {"
                                    "if (forceOff) {$('#btn-save-workout').prop('disabled', true);return;}"
                                    "var nameValue = $('#name-workout').val();"
                                    "var planValue =   $('#plan-workout').val();"
                                    "var creatorValue = $('#creator-workout').val();"
                                    "if (nameValue.length > 0 && creatorValue.length > 0 && planValue.length > 0) {$('#btn-save-workout').prop('disabled', false);}"
                                    "else {$('#btn-save-workout').prop('disabled', true);}"
                                    "}"
                                    );
                
                        QWebEngineScript script;
                        script.setSourceCode(webChannelJs);
                        script.setName("qwebchannel.js");
                        script.setWorldId(QWebEngineScript::MainWorld);
                        script.setInjectionPoint(QWebEngineScript::DocumentCreation);
                        script.setRunsOnSubFrames(false);
                        //        profile->scripts()->insert(script);
                
                        QWebEnginePage *myPage = new QWebEnginePage(profile, ui->webView_createWorkout);
                        ui->webView_createWorkout->setPage(myPage);
                        myPage->scripts().insert(script);
                
                        QWebChannel *channel = new QWebChannel(myPage);
                        ui->webView_createWorkout->page()->setWebChannel(channel);
                        channel->registerObject("workoutCreator", this);
                    }
                }
                
                M Offline
                M Offline
                Munish
                wrote on last edited by
                #11

                @maximus
                Just wanted to know, will c++ objects (workoutCreator) available to other javascript also?
                I am getting "undefined" error while accessing c++ object slots/function from script other than qwebchannel.js

                S 1 Reply Last reply
                0
                • M Munish

                  @maximus
                  Just wanted to know, will c++ objects (workoutCreator) available to other javascript also?
                  I am getting "undefined" error while accessing c++ object slots/function from script other than qwebchannel.js

                  S Offline
                  S Offline
                  SherifOmran
                  wrote on last edited by
                  #12

                  @Munish if you checked the "enable Qt Quick compiler" in the build setting, you may get this error. I got it also.

                  1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    KWanH
                    wrote on last edited by
                    #13

                    when page finish,Run this!

                    	QString js;
                    	QFile jsFile(":/ServiceNumber/Resource/ServiceNumber/qwebchannel.js");
                    	jsFile.open(QIODevice::ReadOnly);
                    	js = jsFile.readAll();
                    	webView->page()->runJavaScript(js);
                    
                    1 Reply Last reply
                    0
                    • M maximus

                      I copied the whole content of qwebchannel.js inside my page just before "new QWebChannel..." and I do not get the error on the Qtcreator console, but still qt is undefined (get the alert message on my webpage).

                      Also to note that I try to set my channel after the page is loaded, and it get triggered 2 times? I only load the URL once. I read on other forums that reloading the page could stop the channel from working, but I am unable to make it work in the first place.

                      ui->webView_workouts->load(QUrl(Environnement::getUrlWorkout()));
                      connect(ui->webView_workouts->page(), SIGNAL(loadFinished(bool)), this, SLOT(connectToJs(bool)));
                      
                      void Main_WorkoutPage::connectToJs(bool result) {
                      
                          qDebug() << "connectToJs!" << result;
                          if (result) {
                              QWebChannel *channel = new QWebChannel(ui->webView_workouts->page());
                              ui->webView_workouts->page()->setWebChannel(channel);
                              channel->registerObject(QString("workoutObject"), this);
                          }
                      }
                      
                      U Offline
                      U Offline
                      Unicode
                      wrote on last edited by
                      #14

                      call page()->setWebChannel() before QWebEngineView::load()

                      ==>
                      .......
                      QWebChannel *channel = new QWebChannel(ui->webView_workouts->page());
                      ui->webView_workouts->page()->setWebChannel(channel);
                      channel->registerObject(QString("workoutObject"), this);
                      ......
                      ui->webView_workouts->load(QUrl(Environnement::getUrlWorkout()));
                      .......

                      H 1 Reply Last reply
                      1
                      • U Unicode

                        call page()->setWebChannel() before QWebEngineView::load()

                        ==>
                        .......
                        QWebChannel *channel = new QWebChannel(ui->webView_workouts->page());
                        ui->webView_workouts->page()->setWebChannel(channel);
                        channel->registerObject(QString("workoutObject"), this);
                        ......
                        ui->webView_workouts->load(QUrl(Environnement::getUrlWorkout()));
                        .......

                        H Offline
                        H Offline
                        hank_yu
                        wrote on last edited by
                        #15

                        @Unicode this way works! thank you!

                        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