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. Newable script objects: QScriptEngine vs. QQMLEngine/QJSEngine
Forum Updated to NodeBB v4.3 + New Features

Newable script objects: QScriptEngine vs. QQMLEngine/QJSEngine

Scheduled Pinned Locked Moved QML and Qt Quick
4 Posts 3 Posters 2.2k 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 Offline
    J Offline
    jsprenkle
    wrote on last edited by
    #1

    Good morning,
    I'm interested in adding C++ objects that can be instantiated from a script but I'm not sure how it works when combined with QtQuick.

    I'm trying to use the Q_SCRIPT_DECLARE_QMETAOBJECT macro and scriptValueFromQMetaObject<>() method to create newable script objects.

    My main creates a QQuickView() object.
    That object contains an engine() method that returns a QQmlEngine which inherits from QJSEngine.
    The scriptValueFromQMetaObject method is derived from QScriptEngine() not QJSEngine.
    I don't see an equivalent of scriptValueFromQMetaObject in QJSEngine.

    Is there a way to 'register' my C++ class with QJSEngine? I assume I have to use the javascript engine associated with the QML view. That way the class will be available in the script context associated with the QML code.

    Thanks!

    1 Reply Last reply
    0
    • ? Offline
      ? Offline
      A Former User
      wrote on last edited by
      #2

      Hi,

      I think it is not possible by now to create custom classes that are newable in script code, at least I couldn't figure out how to do it.

      As a workaround you can create some sort of QObject derived "master object" that is set as a global property in your script context and give it a Q_INVOKABLE method that acts as factory for the objects, that you want to instantiate dynamically in your script, like:

      @
      Q_INVOKABLE QObject* myFactoryForObjectsOfTypeA() const {
      QObject* obj = new ObjectOfTypeA;
      QQmlEngine::setObjectOwnership(obj, QQmlEngine::JavaScriptOwnership);
      return obj;
      }
      @

      I have working code for this on my harddrive. If you like the idea then I can post a more complete example.

      Cheers!

      1 Reply Last reply
      0
      • J Offline
        J Offline
        jsprenkle
        wrote on last edited by
        #3

        I was able to figure out something that might work.

        As a work around I declared a function as Q_INVOKABLE in the object that the script context inherits from. In that object I create a javascript compatible object and return it. A simple new myobject() also works but I don't think it confers ownership to the script and it will never be deleted.

        @QJSValue contextclass::myobject( int Row, int Column )
        {
        Application* app = dynamic_cast< Application* >( QCoreApplication::instance() );
        if ( !app )
        throw ::std::runtime_error( "Could not obtain application object" );
        // this confers ownership to javascript but not sure when garbage collection will happen
        return app->view->engine()->newQObject( new myobject() );
        }
        @

        I also tried the following. It compiled but I never could get the script to invoke it:

        @ // create a script wrapped proxy object as a QScriptValue
        cellReferenceFactory = view->engine()->newQObject( &_myobject );
        // Create a script wrapped QJSValue that will instantiate a new object
        cellReferenceInstance = cellReferenceFactory.callAsConstructor();
        // tell the engine to create a property that will instantiate a myobject object
        view->engine()->globalObject().setProperty( "myobject", cellReferenceInstance );
        @

        I tried to create it using "Qt.myobject" and "Qt.myobject()" ( view is the QQuickView for the application)

        1 Reply Last reply
        0
        • R Offline
          R Offline
          richardo
          wrote on last edited by richardo
          #4

          You could also try to use your C++ object as a prototype:

          QJSValue myType = engine->evaluate("function MyType() {}");
          myType.setPrototype( engine->newQObject(new MyTypeCpp));
          

          I've not tried this, but this could work. Probably you would to have to set myType as property in the JSEngine::globalObject().

          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