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. Pulling QList from C++ to qml

Pulling QList from C++ to qml

Scheduled Pinned Locked Moved QML and Qt Quick
4 Posts 2 Posters 6.8k 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.
  • F Offline
    F Offline
    fdrk
    wrote on last edited by
    #1

    Hello,

    Last year I've used a QList<QObject*> inside QML by passing the list to through a QVariant to QML the following way:
    @
    QMetaObject::invokeMethod(rootObject(), "refreshData", Q_ARG(QVariant, QVariant::fromValue(qListOfQObjectPtr));
    @
    I have this working in a project without Q_DECLARE_METATYPE(MyClassInheritsQObject*) macro where it simply compiles.
    In all other projects I have to use the macro or QVariant complains it doesn't know the type.

    I was wondering how it is possible that last year's project just works (and compiles up to today) without the metatype macro.
    I'm using QObject* and I can call Q_INVOKABLE functions with it inside QML but there is no Q_DECLARE_METATYPE macro anywhere in the project (even searched with Notepad++ through all project files).

    How is it possible that QML knows my QObject subclass?
    Btw: I'm also not having any custom QML items using registerType, it's just a plain Object subclass with some data and Q_INVOCABLE functions.

    Another issue I'm having is that it seems impossible to read from a QVariantList which contains QObject*:
    QMetaObject::invokeMethod(rootObject(), "refreshData", Q_ARG(QVariant, myVariantList));
    The QML function refreshData(arr) can access arr but nothing can be done with the variant (which contains a QObject*).
    How can I call for example a Q_INVOCABLE function from the variant?

    1 Reply Last reply
    0
    • C Offline
      C Offline
      chriadam
      wrote on last edited by
      #2

      Hi,

      Function invocation on a QObject* in QML is pretty special - the function signature is matched as closely as possible by introspecting the methods reported by the object's metaobject, and then the matching method is invoked. Q_INVOKABLE like Q_SLOT etc makes the function available through the metaobject by registering it with the metaobject system.

      Note that QList<QObject*> has definitely been declared as a metaobject by QML internally (since we use QList<QObject*> in various places, eg the implementation of the QtQuick Item's "children" property requires (IIRC) QList<QObject*> to be registered as a metatype already.

      So, in short: QML doesn't know your QObject subclass. But, so long as you make your derived class' methods and properties available through the metaobject system (via Q_PROPERTY, Q_INVOKABLE, Q_SLOTS, Q_ENUM etc), QML is able to introspect instance objects' metaobjects and access those methods and properties.

      Regarding the QVariantList issue: this is interesting, as I thought QVariantList was automatically converted to JavaScript array. If the variant containing the QObject* isn't being transformed into a JavaScript object wrapping a QObject*, then either something is going wrong (eg, unregistered type, bug, etc) or something else is going on. Are you able to call a C++ function from within the "refreshData" function, where that C++ function takes a QVariant arg and returns a QObject* value (and uses QVariant::fromValue<QObject*>(variant) to get it from the arg)?

      Cheers,
      Chris.

      1 Reply Last reply
      0
      • F Offline
        F Offline
        fdrk
        wrote on last edited by
        #3

        Thank you for your reply.
        So if do not need the Q_DECLARE_METATYPE macro if I return my pointer as QObject* but I do need the macro if I want to return MyClass* regardless whether my called functions are Q_INVOKABLE (or registrated through some other way) or not.

        With what I learned from this I was able to work around the QVariantList problem by simply sending the variant as a QObject* instead of MyClass*

        @

        myVariantList.append(QVariant::fromValue((QObject*)new DataContainer("data from myVariantList")));
        
        QMetaObject::invokeMethod(rootObject()
                                    , "refreshData"
                                    , Q_ARG(QVariant, myVariantList)
                                 );
        

        @
        @
        function refreshData(arrData)
        {
        myText.text = "";
        for (var i = 0; i < arrData.length; ++i)
        {
        myText.text += arrData[i].getData() + "\n";
        }
        }//everything works :)
        @

        I believe that if I want to be able to use the DataContainer class I need the Q_DECLARE_METATYPE macro to tell QVariant what it is but also a registration of the type with qmlRegisterType so that it actually works inside QML.
        I will try this out later but I do not understand why everything just works with QObject* and why it doesn't with MyClass* since MyClass IS a QObject after all.

        http://doc.qt.nokia.com/4.7-snapshot/qdeclarativeengine.html#qmlRegisterType

        1 Reply Last reply
        0
        • F Offline
          F Offline
          fdrk
          wrote on last edited by
          #4

          I figured that I was missing an include somewhere so that in one project I had to do nothing while in the other my code just worked. After a search it appears that including qdeclarativecontext.h does the job.
          So I need to put this macro in the .cpp file or include the qdeclarativecontext.h header.

          C:\Qt\4.8.0\src\declarative\qml\qdeclarativecontext.h (1 hits)
          Line 110: Q_DECLARE_METATYPE(QList<QObject*>)

          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