Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QJSEngine copy?
Forum Update on Monday, May 27th 2025

QJSEngine copy?

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
8 Posts 2 Posters 902 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.
  • T Offline
    T Offline
    Tarae
    wrote on last edited by
    #1

    Is there a way how to copy one instance of QJSEngine to another including variables and functions?

      QJSEngine engine1, engine2;
    
      engine1.evaluate("function sum(x, y){ return x + y;}");
      engine1.globalObject().setProperty("a", 1);
      engine1.evaluate("var b = 2;");
    
      //something like engine2 = engine1;
    
      qDebug() << engine2.evaluate("sum(a,b)").toString(); //3
    
    JKSHJ 1 Reply Last reply
    0
    • T Tarae

      Is there a way how to copy one instance of QJSEngine to another including variables and functions?

        QJSEngine engine1, engine2;
      
        engine1.evaluate("function sum(x, y){ return x + y;}");
        engine1.globalObject().setProperty("a", 1);
        engine1.evaluate("var b = 2;");
      
        //something like engine2 = engine1;
      
        qDebug() << engine2.evaluate("sum(a,b)").toString(); //3
      
      JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #2

      Hi, and welcome!

      @Tarae said in QJSEngine copy?:

      Is there a way how to copy one instance of QJSEngine to another

      No. QJSEngine is a QObject, and QObjects cannot be copied.

      However, you can copy the engine's Global Object (JavaScript object): https://doc.qt.io/qt-5/qjsengine.html#globalObject

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      T 1 Reply Last reply
      4
      • JKSHJ JKSH

        Hi, and welcome!

        @Tarae said in QJSEngine copy?:

        Is there a way how to copy one instance of QJSEngine to another

        No. QJSEngine is a QObject, and QObjects cannot be copied.

        However, you can copy the engine's Global Object (JavaScript object): https://doc.qt.io/qt-5/qjsengine.html#globalObject

        T Offline
        T Offline
        Tarae
        wrote on last edited by
        #3

        @JKSH Thank you.
        But I can't see, how a copy of global object can solve my problem.
        Is there a way how to create another engine with copy of global object?

        // I have engine1 with variables and functions.
          QJSEngine engine1;
          engine1.evaluate("function sum(x, y){ return x + y;}");
          engine1.globalObject().setProperty("a", 1);
          engine1.evaluate("var b = 2;");
        
        // I create copy of global object, how you suggest.
         QJSValue globalObject = engine1.globalObject();
         QJSValue copyOfGlobalObject = deepCopy(globalObject);
         //BTW How to do deep copy of QJSValue if it is a object (isObject() returns true)?
         
        //And how to create new engine when I have copy of global object?
        // I would need something like this:  
         QJSEngine engine2 = QJSEngine(copyOfGlobalObject); //creates instance of engine with global object
        // or this:
        QJSEngine engine2;
        engine2.globalObject() = copyOfGlobalObject; // sets global object of engine
        
        
        qDebug() << engine2.evaluate("sum(a,b)").toString(); //3
        
        JKSHJ 1 Reply Last reply
        0
        • T Tarae

          @JKSH Thank you.
          But I can't see, how a copy of global object can solve my problem.
          Is there a way how to create another engine with copy of global object?

          // I have engine1 with variables and functions.
            QJSEngine engine1;
            engine1.evaluate("function sum(x, y){ return x + y;}");
            engine1.globalObject().setProperty("a", 1);
            engine1.evaluate("var b = 2;");
          
          // I create copy of global object, how you suggest.
           QJSValue globalObject = engine1.globalObject();
           QJSValue copyOfGlobalObject = deepCopy(globalObject);
           //BTW How to do deep copy of QJSValue if it is a object (isObject() returns true)?
           
          //And how to create new engine when I have copy of global object?
          // I would need something like this:  
           QJSEngine engine2 = QJSEngine(copyOfGlobalObject); //creates instance of engine with global object
          // or this:
          QJSEngine engine2;
          engine2.globalObject() = copyOfGlobalObject; // sets global object of engine
          
          
          qDebug() << engine2.evaluate("sum(a,b)").toString(); //3
          
          JKSHJ Offline
          JKSHJ Offline
          JKSH
          Moderators
          wrote on last edited by JKSH
          #4

          @Tarae The documentation says (https://doc.qt.io/qt-5.12/qjsvalue.html#details ):

          Note that a QJSValue for which isObject() is true only carries a reference to an actual object; copying the QJSValue will only copy the object reference, not the object itself. If you want to clone an object (i.e. copy an object's properties to another object), you can do so with the help of a for-in statement in script code, or QJSValueIterator in C++.

          I believe you can use QJSValueIterator to iterate across every property in the 1st global object. Then, you can copy each property into the 2nd global object.

          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

          T 1 Reply Last reply
          0
          • JKSHJ JKSH

            @Tarae The documentation says (https://doc.qt.io/qt-5.12/qjsvalue.html#details ):

            Note that a QJSValue for which isObject() is true only carries a reference to an actual object; copying the QJSValue will only copy the object reference, not the object itself. If you want to clone an object (i.e. copy an object's properties to another object), you can do so with the help of a for-in statement in script code, or QJSValueIterator in C++.

            I believe you can use QJSValueIterator to iterate across every property in the 1st global object. Then, you can copy each property into the 2nd global object.

            T Offline
            T Offline
            Tarae
            wrote on last edited by
            #5

            @JKSH OK, thank you for help, it looked great at first, but there is another problem: cannot set value created in a different engine

                  QJSEngine engine1, engine2;
                  engine1.evaluate("function sum(x, y){ return x + y;}");
                  engine1.globalObject().setProperty("a", 1);
                  engine1.evaluate("var b = 2;");
            
                  QJSValueIterator it(engine1.globalObject());
                  while (it.hasNext()) {
                      it.next();
                      qDebug() << it.name() << ": " << it.value().toString();
                      engine2.globalObject().setProperty(it.name(), it.value());
                  }
            
                  qDebug() << engine2.evaluate("sum(a,b)").toString(); //3
            

            output looks like this:

            ...
            "sum" :  "function sum() { [native code] }"
            QJSValue::setProperty(sum) failed: cannot set value created in a different engine 
            "a" :  "1"
            QJSValue::setProperty(a) failed: cannot set value created in a different engine
            "b" :  "2"
            QJSValue::setProperty(b) failed: cannot set value created in a different engine
            "sum" :  "function sum() { [native code] }"
            QJSValue::setProperty(sum) failed: cannot set value created in a different engine
            "a" :  "1"
            QJSValue::setProperty(a) failed: cannot set value created in a different engine
            "b" :  "2"
            QJSValue::setProperty(b) failed: cannot set value created in a different engine
            "ReferenceError: a is not defined"
            

            Any idea how to solve this?

            1 Reply Last reply
            0
            • JKSHJ Offline
              JKSHJ Offline
              JKSH
              Moderators
              wrote on last edited by
              #6

              Hmm... That's unfortunate.

              For things like numbers/strings you could bypass the restriction by calling QJSValue::toNumber()/QJSValue::toString() first before calling setProperty(). I can't think of a way to copy functions though.

              Can you elaborate on why you want to copy the engine?

              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

              T 1 Reply Last reply
              0
              • JKSHJ JKSH

                Hmm... That's unfortunate.

                For things like numbers/strings you could bypass the restriction by calling QJSValue::toNumber()/QJSValue::toString() first before calling setProperty(). I can't think of a way to copy functions though.

                Can you elaborate on why you want to copy the engine?

                T Offline
                T Offline
                Tarae
                wrote on last edited by
                #7

                @JKSH What I want to accomplish is creating a lot of engines. All engines share some functions and variables. But not all of them, I can't use one engine for everything. I could define all functions and variables in each engine, but running JSEngine::execute() takes a lot of time. So I wanted to create one engine, define shared functions and variables in it and copy it to others engines.

                Code:
                What I have:

                QString sharedScript = readFile("shared_script.js"); //large file
                
                QJSEngine engine1;
                engine1.evaluate(sharedScript); //takes long
                QString engine1script = readFile("script1.js");
                engine1.evaluate(engine1script);
                
                //...
                
                QJSEngine engine1000;
                engine1000.evaluate(sharedScript); //takes long
                QString engine1000script = readFile("script1000.js");
                engine1000.evaluate(engine1000script);
                

                What I want:

                QString sharedScript = readFile("shared_script.js"); //long file
                QJSEngine sharedEngine;
                sharedEngine.evaluate(sharedScript); //takes long 
                
                QJSEngine engine1 = copyOf(sharedEngine); //fast
                QString engine1script = readFile("script1.js");
                engine1.evaluate(engine1script);
                
                //...
                
                QJSEngine engine1000 = copyOf(sharedEngine); //fast
                QString engine1000script = readFile("script1000.js");
                engine1000.evaluate(engine1script);
                
                JKSHJ 1 Reply Last reply
                0
                • T Tarae

                  @JKSH What I want to accomplish is creating a lot of engines. All engines share some functions and variables. But not all of them, I can't use one engine for everything. I could define all functions and variables in each engine, but running JSEngine::execute() takes a lot of time. So I wanted to create one engine, define shared functions and variables in it and copy it to others engines.

                  Code:
                  What I have:

                  QString sharedScript = readFile("shared_script.js"); //large file
                  
                  QJSEngine engine1;
                  engine1.evaluate(sharedScript); //takes long
                  QString engine1script = readFile("script1.js");
                  engine1.evaluate(engine1script);
                  
                  //...
                  
                  QJSEngine engine1000;
                  engine1000.evaluate(sharedScript); //takes long
                  QString engine1000script = readFile("script1000.js");
                  engine1000.evaluate(engine1000script);
                  

                  What I want:

                  QString sharedScript = readFile("shared_script.js"); //long file
                  QJSEngine sharedEngine;
                  sharedEngine.evaluate(sharedScript); //takes long 
                  
                  QJSEngine engine1 = copyOf(sharedEngine); //fast
                  QString engine1script = readFile("script1.js");
                  engine1.evaluate(engine1script);
                  
                  //...
                  
                  QJSEngine engine1000 = copyOf(sharedEngine); //fast
                  QString engine1000script = readFile("script1000.js");
                  engine1000.evaluate(engine1script);
                  
                  JKSHJ Offline
                  JKSHJ Offline
                  JKSH
                  Moderators
                  wrote on last edited by
                  #8

                  @Tarae As a workaround, try splitting shared_script.js into 2 parts:

                  (i) A part that contains just the function definitions
                  (ii) A part that contains function calls.

                  My hypothesis is that evaluate()-ing (i) should be faster than (ii).

                  So, you could try:

                  1. Run (i) and (ii) in engine1
                  2. Run only (i) in engine2
                  3. Use QJSValueIterator to copy non-function properties to engine2, using QJSValue::toNumber() / QJSValue::toString() / QJSValue::toVariant() first

                  Another thing you could try is putting different engines in different threads (although you must be careful with thread programming)

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  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