Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QQmlPropertyMap as return type



  • Hi,
    I want wo exchange dynamic data between C++ and QML (again...). My idea is: I create a C++-Class derived from QQmlPropertyMap. Then in C++ I create lists from that kind of object and I register an QObject to QML, which has a function that can return those objects:

    C++:

      broker = new DataBroker(...);
      engine->rootContext()->setContextProperty("broker", broker);
    

    QML:

          // broker.loadQml return a QQmlPropertyMap *
          // does not matter if casted to QObject*
          // it does not work to access or modify properties
          data = broker.loadQml("1234");
    

    When using QQmlPropertyMap as return type of the function, it even gives an error: "Unknown method return type: QQmlPropertyMap*"
    When usign QObject* as return type (that means cast the QQmlPropertyMap* to QObject*) it does not give an error, but properties are not accessible to QML.

    Can anyone give a hint?

    Thanks and best regards,
    Tobias


  • Qt Champions 2017

    May be you missed registering the meta type as QQmlPropertyMap is not a standard type.

    C++ code
    
    qRegisterMetaType<QQmlPropertyMap*>("QQmlPropertyMap");
    
    QQmlPropertyMap* MyAuth::getValues()
    {
        QQmlPropertyMap *ownerData = new QQmlPropertyMap;
        ownerData->insert("name", QVariant(QString("Dheerendra")));
        ownerData->insert("email", QVariant(QString("dheerendra@pthinks.com")));
        return ownerData;
    }
    
    QML Code
    
                      var obj = login.getValues();
                      console.log("**** =",obj.name)
                      console.log("**** =",obj.email)
    


  • @dheerendra said in QQmlPropertyMap as return type:

    qRegisterMetaType<QQmlPropertyMap*>("QQmlPropertyMap");

    Jepp... when registering the Meta-Type then at least the error goes away, but the properties are still inaccessible :-/

    Best Regards,
    Tobias


  • Qt Champions 2017

    Please do the code as suggested by me. Otherwise you can share complete code snippet. We will help you.



  • I did.

    My feeling is, the problem is in qv4objectwrapper.cpp, in function CallArgument::initAsType. I think, using QQmlPropertyMap is only valid if set as context property (and not as return type of a function)?

    Best Regards,
    Tobias


  • Qt Champions 2018

    Can you share a reproducible minimal example?

    I have no problems using QQmlPropertyMap* as a return type in my projects.
    Make sure to qmlRegisterType QQmlPropertyMap, not QQmlPropertyMap*.



  • main:

    int main(int argc, char *argv[])
    {
      qRegisterMetaType<QQmlPropertyMap*>("QQmlPropertyMap");
      qmlRegisterType<QQmlPropertyMap>();
      TestQmlJsonConnect::exec(argc, argv);
    
      return 0;
    }
    
    void TestQmlJsonConnect::exec(int argc, char *argv[])
    {
      broker = new DataBroker(provider, "JsonData");
      Setup setup;
      quick_test_main_with_setup(argc, argv, "TestQmlJsonConnect", ":/qml", &setup);
      delete broker;
      delete provider;
    }
    void Setup::qmlEngineAvailable(QQmlEngine *engine)
    {
      engine->rootContext()->setContextProperty("broker", broker);
    }
    
    QQmlPropertyMap *DataBroker::loadQml(const QUuid &uuid)
    {
      QQmlPropertyMap *p = new QQmlPropertyMap();
      p->insert("info", "test");
      return p;
    }
    
    import QtQuick 2.12
    import QtTest 1.12
    
    TestCase {
        name: "tst_QmlJsonConnect.qml"
    
        function test_one() {
          data = broker.loadQml("1234");
          console.log(data);              // qml: [object Object]
          console.log(data.info);         // qml: undefined
          compare(data.info, "test");     // compare fails -> test ends
          data.info = "Hallo";
          compare(data.info, "Hallo");
        }
    }
    

    :-/



  • Cannot build your example rn, but have you ever tried to print 'data' keys? Like console.log(Object.keys(data)).



  • @IntruderExcluder

    You are right... I did a really small Application (about 3 lines of code :-)) and there it works. I am going to check, what is wrong with my real "Application" -> This is currently only a Testapplication (using testlib and testcases). Maybe the environment is different there...

    Thanks for help,
    Tobias



  • @topse

    Found the bug:

    var data = broker.loadQml(...);
    

    Forget the var :-(

    Thanks for help - it was very appreciated to read, that in principle using QQmlPropertyMap as return type works.

    Best Regards,
    Tobias


Log in to reply