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. How to access QJSValue's QQmlEngine in Q_INVOKABLE to support callback pattern for C++ models
Forum Updated to NodeBB v4.3 + New Features

How to access QJSValue's QQmlEngine in Q_INVOKABLE to support callback pattern for C++ models

Scheduled Pinned Locked Moved Solved QML and Qt Quick
3 Posts 2 Posters 303 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.
  • L Offline
    L Offline
    Lord_Naikon
    wrote on last edited by
    #1

    I have code like this:

    class Foo : QObject { 
      ...
      Q_INVOKABLE void bar(const QJSValue &callback) {
         ... asynchronous code resulting in:
         auto e = qmlEngine(this);
         callback.call({e->toScriptValue(result)});
      }
    }
    

    Foo is created in C++ and exposed to QML via a QAbstractListModel implementation.

    Now, because Foo is not constructed by QQmlEngine, qmlEngine(this) in bar() will return nullptr, leaving me with no way to actually call the callback with an argument that is not a primitive value.

    I half expected that the object would get associated with the engine as soon as the engine called the Q_INVOKABLE, but that is apparently not the case.

    There used to be a QJSValue::engine() method, that would have allowed me to get the engine from the callback itself, but it was deprecated for some reason in Qt 5 and does not exist in Qt 6. This method would be the ideal solution to this problem.

    I've now worked around it by having a helper object (constructed by QML) that calls the callback on Foo::bar()'s behalf, essentially proxying access to Foo. This is less than ideal for obvious reasons. Another workaround is to have Foo depend on a QQmlEngine instance, which it can use to construct the callback's argument list. I don't like this solution because then I would have to store the engine instance inside the data model.

    How would you solve this problem? Or is it time for a feature request :)

    1 Reply Last reply
    0
    • K Offline
      K Offline
      Kai Nickel
      wrote on last edited by
      #2

      Just a lucky shot: did you try using qjsEngine(this) instead of qmlEngine(this)?

      L 1 Reply Last reply
      2
      • K Kai Nickel

        Just a lucky shot: did you try using qjsEngine(this) instead of qmlEngine(this)?

        L Offline
        L Offline
        Lord_Naikon
        wrote on last edited by
        #3

        @Kai-Nickel said in How to access QJSValue's QQmlEngine in Q_INVOKABLE to support callback pattern for C++ models:

        Just a lucky shot: did you try using qjsEngine(this) instead of qmlEngine(this)?

        I did not and I'm happy to report that qjsEngine() does work!

        Looking at the source code of qmlEngine() vs qjsEngine() it is obvious why: qmlEngine() only works if there is a qml context for that object.

        I was under the assumption that qmlEngine() simply called qobject_cast<QQmlEngine*>(qjsEngine(obj)), which is why I didn't look at the differences between the two. Evidently my assumptions proved wrong.

        QQmlEngine *qmlEngine(const QObject *obj)
        {
            QQmlData *data = QQmlData::get(obj, false);
            if (!data || !data->context)
                return nullptr;
            return data->context->engine;
        }
        
        QJSEngine *qjsEngine(const QObject *object)
        {
            QQmlData *data = QQmlData::get(object, false);
            if (!data || data->jsWrapper.isNullOrUndefined())
                return nullptr;
            return data->jsWrapper.engine()->jsEngine();
        }
        
        1 Reply Last reply
        0
        • L Lord_Naikon has marked this topic as solved on

        • Login

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