Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. 'evaluateJavaScript()' doesn't return any value. (content position on page wanted)
Forum Updated to NodeBB v4.3 + New Features

'evaluateJavaScript()' doesn't return any value. (content position on page wanted)

Scheduled Pinned Locked Moved Solved General and Desktop
qt4webkitjavascript qwebjavascript
24 Posts 3 Posters 15.5k 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.
  • J JonB
    28 Sept 2017, 08:46

    @ShivaHaze
    To test whether we can apply a really simple fix, take the principle from https://stackoverflow.com/a/20894436/489865 and put in a delay between the 2 evaluateJavaScript()s in the test:

    evaluateJavaScript("window.onload = function () { window.alert('Called from onload'); }");
    
    QTime dieTime= QTime::currentTime().addSecs(5);
    while (QTime::currentTime() < dieTime)
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    
    evaluateJavaScript("window.alert('Called directly');");
    

    This will result in a 5 second delay. If you then find that you get the Called from onload message before the Called directly we are in business! In that case, we would change the precise delay code, as that posted example is not "right", but it's a quick way to see if the principle works...?

    S Offline
    S Offline
    ShivaHaze
    wrote on 28 Sept 2017, 08:51 last edited by
    #21

    @JNBarchan I'm at work right now so I can't test too much, but from what I see the program is def. waiting. :-)
    I guess applying the delay to the right point will do the trick, but I can only verify that later today. :-)
    Really interested to try this out, I'll keep you up-to-date!

    J 1 Reply Last reply 28 Sept 2017, 08:56
    0
    • S ShivaHaze
      28 Sept 2017, 08:51

      @JNBarchan I'm at work right now so I can't test too much, but from what I see the program is def. waiting. :-)
      I guess applying the delay to the right point will do the trick, but I can only verify that later today. :-)
      Really interested to try this out, I'll keep you up-to-date!

      J Online
      J Online
      JonB
      wrote on 28 Sept 2017, 08:56 last edited by
      #22

      @ShivaHaze
      The delay principle will only work provided that the web view continues to load/process during the delay. That is what I am hoping the QCoreApplication::processEvents() will allow....

      S 1 Reply Last reply 28 Sept 2017, 23:28
      1
      • J JonB
        28 Sept 2017, 08:56

        @ShivaHaze
        The delay principle will only work provided that the web view continues to load/process during the delay. That is what I am hoping the QCoreApplication::processEvents() will allow....

        S Offline
        S Offline
        ShivaHaze
        wrote on 28 Sept 2017, 23:28 last edited by ShivaHaze
        #23

        @JNBarchan said in 'evaluateJavaScript()' doesn't return any value. (content position on page wanted):

        @ShivaHaze
        The delay principle will only work provided that the web view continues to load/process during the delay. That is what I am hoping the QCoreApplication::processEvents() will allow....

        You are a god to me - Thanks so much!
        It works perfectly!
        1 second delay is enough to get the job done. :-)

        Whoever is interested in the full code - here is my full mainwindow.cpp - the only file I really touched until this point. :-)

        #include "mainwindow.h"
        #include "ui_mainwindow.h"
        
        #include <string>
        #include <iostream>
        #include <stdlib.h>
        #include <stdio.h>
        
        #include <QMainWindow>
        #include <QApplication>
        #include <Qt>
        #include <QDebug>
        #include <QWebView>
        #include <QWebPage>
        #include <QWebFrame>
        #include <QtWebKit>
        #include <QScrollBar>
        #include <QScrollArea>
        #include <QString>
        #include <QTimer>
        
        using namespace std;
        
        MainWindow::MainWindow(QWidget *parent) :
          QMainWindow(parent),
          ui(new Ui::MainWindow)
        {
          ui->setupUi(this);
        
          // Configurating Application-Window
          setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint);
          setFixedSize(width(), height());
        
          // Object-Reference Shortcuts
          QWebFrame *MF = ui->webView->page()->mainFrame();
        
          // Deactivating Scrolling-Bars
          MF->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
          MF->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
        
          QTime dieTime= QTime::currentTime().addSecs(1);
          while (QTime::currentTime() < dieTime)
              QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
        
          QVariant bodytop  = MF->evaluateJavaScript("document.body.getBoundingClientRect().top");
          QVariant bodyleft = MF->evaluateJavaScript("document.body.getBoundingClientRect().left");
          QVariant elemtop  = MF->evaluateJavaScript("document.getElementById('user_reg').getBoundingClientRect().top");
          QVariant elemleft = MF->evaluateJavaScript("document.getElementById('user_reg').getBoundingClientRect().left");
        
          qDebug() << "Body Top: " << bodytop.toInt() << " Body Left: " << bodyleft.toInt() << " Elem Top: " << elemtop.toInt() << " Elem Left: " << elemleft.toInt();
        }
        
        MainWindow::~MainWindow()
        {
          delete ui;
        }
        

        Here you can see the console output before and after applying the delay. :-)

        Console output before & after

        J 1 Reply Last reply 29 Sept 2017, 07:59
        0
        • S ShivaHaze
          28 Sept 2017, 23:28

          @JNBarchan said in 'evaluateJavaScript()' doesn't return any value. (content position on page wanted):

          @ShivaHaze
          The delay principle will only work provided that the web view continues to load/process during the delay. That is what I am hoping the QCoreApplication::processEvents() will allow....

          You are a god to me - Thanks so much!
          It works perfectly!
          1 second delay is enough to get the job done. :-)

          Whoever is interested in the full code - here is my full mainwindow.cpp - the only file I really touched until this point. :-)

          #include "mainwindow.h"
          #include "ui_mainwindow.h"
          
          #include <string>
          #include <iostream>
          #include <stdlib.h>
          #include <stdio.h>
          
          #include <QMainWindow>
          #include <QApplication>
          #include <Qt>
          #include <QDebug>
          #include <QWebView>
          #include <QWebPage>
          #include <QWebFrame>
          #include <QtWebKit>
          #include <QScrollBar>
          #include <QScrollArea>
          #include <QString>
          #include <QTimer>
          
          using namespace std;
          
          MainWindow::MainWindow(QWidget *parent) :
            QMainWindow(parent),
            ui(new Ui::MainWindow)
          {
            ui->setupUi(this);
          
            // Configurating Application-Window
            setWindowFlags(Qt::Window | Qt::WindowMinimizeButtonHint | Qt::WindowCloseButtonHint);
            setFixedSize(width(), height());
          
            // Object-Reference Shortcuts
            QWebFrame *MF = ui->webView->page()->mainFrame();
          
            // Deactivating Scrolling-Bars
            MF->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);
            MF->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
          
            QTime dieTime= QTime::currentTime().addSecs(1);
            while (QTime::currentTime() < dieTime)
                QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
          
            QVariant bodytop  = MF->evaluateJavaScript("document.body.getBoundingClientRect().top");
            QVariant bodyleft = MF->evaluateJavaScript("document.body.getBoundingClientRect().left");
            QVariant elemtop  = MF->evaluateJavaScript("document.getElementById('user_reg').getBoundingClientRect().top");
            QVariant elemleft = MF->evaluateJavaScript("document.getElementById('user_reg').getBoundingClientRect().left");
          
            qDebug() << "Body Top: " << bodytop.toInt() << " Body Left: " << bodyleft.toInt() << " Elem Top: " << elemtop.toInt() << " Elem Left: " << elemleft.toInt();
          }
          
          MainWindow::~MainWindow()
          {
            delete ui;
          }
          

          Here you can see the console output before and after applying the delay. :-)

          Console output before & after

          J Online
          J Online
          JonB
          wrote on 29 Sept 2017, 07:59 last edited by JonB
          #24

          @ShivaHaze
          @ShivaHaze said in 'evaluateJavaScript()' doesn't return any value. (content position on page wanted):

          You are a god to me - Thanks so much!

          I think you might have meant "good" rather than "god" ;-)

          I am very pleased this approach has worked for you. It is potentially useful for me to know for my own work one day. Had I realized you had not tried the "delay" principle earlier, we would have got there quicker.

          The actual implementation of the delay loop is "naughty". It will mean that your application is "running busily" (i.e. using CPU time, potentially blocking other applications) for most of 1 second. If an expert here looks at it, please don't shout at me! Like I said, I got it from elsewhere as "quick & dirty". For your purposes it's probably fine, and we achieved it without you having to do slots & signals which you were not keen on learning at this stage.

          If you feel like you want to improve/experiment, in the same stackoverflow thread have a look at https://stackoverflow.com/a/3756341/489865, leveraging QWaitCondition, whose description sounds like it should have the same effect without the "busy blocking":

          class SleepSimulator{
               QMutex localMutex;
               QWaitCondition sleepSimulator;
          public:
              SleepSimulator::SleepSimulator()
              {
                  localMutex.lock();
              }
              void sleep(unsigned long sleepMS)
              {
                  sleepSimulator.wait(&localMutex, sleepMS);
              }
              void CancelSleep()
              {
                  sleepSimulator.wakeAll();
              }
          };
          

          Certainly I would try it. If you copied that class into your code, you would call it (I assume) via:

          SleepSimulator* sleep = new SleepSimulator();
          sleep->sleep(1000);
          delete sleep;
          

          Now I think you can get down to the real coding you want to do for your application! Best of luck.

          1 Reply Last reply
          1

          21/24

          28 Sept 2017, 08:51

          • Login

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