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 24.3k 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
    #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