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 export complex C++ data to qml

How to export complex C++ data to qml

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
9 Posts 4 Posters 764 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.
  • G Offline
    G Offline
    GregWilsonLindberg
    wrote on last edited by
    #1

    I'm trying to export from c++ into qml a c++ class that has QList<QObject *> to other classes. I've registered all of the classes, but I haven't been able to figure out how to tell qml what type of object the QList<QObject *> points to.

    I use a xxx.rootContext()->setContextProperty() call to tell qml about the top level object structure, but I don't know how to tell qml what the QList<QObject *>'s point to (if there is a way).

    I need to pass the QList<QObject *>'s to other QtQuick display elements as models.

    In a straight c++ description what I'm trying to pass along looks like:

    class class_a {
    QString name_a;
    int num_a;
    int num_b;
    }
    class class_b {
    QString name_b;
    int num_x;
    int numY;
    }

    class class_C {
    QString name_c;
    int num_a;
    int num_b;
    class_a a_array[];
    class_b b_array[];
    }

    In the QML'd version I have:

    class class_C {
    Q_OBJECT

    Q_PROPERTY(QString nodeName READ nodeName)
    Q_PROPERTY(int numA READ numA)
    Q_PROPERTY(int numB READ numB)

    Q_PROPERTY(QList<QObject*> class_a)
    Q_PROPERTY(QList<QObject*> class_b)

    ...
    }

    then in main:

    qmlRegisterUncreatableType<class_a>("Class_a", 1, 0, "Class_a",
    QStringLiteral("CanNodeInfo should not be created in QML."));
    qmlRegisterUncreatableType<class_b>("Class_b", 1, 0, "Class_c",
    QStringLiteral("CanNodeInfo should not be created in QML."));
    qmlRegisterUncreatableType<class_C>("Class_c", 1, 0, "Class_c",
    QStringLiteral("CanNodeInfo should not be created in QML."));

    and:

    engine.rootContext()->setContextProperty(QStringLiteral("class_c_List"), QVariant::fromValue(Cpp2QmlInterfaceClass::getClassC()));

    This has allowed me to access the members of Class c in qml, but (as I have said) I don't see any way to tell qml what the QList<QObject *>'s point to.

    Am I missing something, and if so can someone point me to the relevant documentation? Or is this just something that qml can't do yet (or maybe ever)?

    How have others handled complex nested data structures?

    Regards,
    Greg

    jsulmJ 1 Reply Last reply
    0
    • G GregWilsonLindberg

      I'm trying to export from c++ into qml a c++ class that has QList<QObject *> to other classes. I've registered all of the classes, but I haven't been able to figure out how to tell qml what type of object the QList<QObject *> points to.

      I use a xxx.rootContext()->setContextProperty() call to tell qml about the top level object structure, but I don't know how to tell qml what the QList<QObject *>'s point to (if there is a way).

      I need to pass the QList<QObject *>'s to other QtQuick display elements as models.

      In a straight c++ description what I'm trying to pass along looks like:

      class class_a {
      QString name_a;
      int num_a;
      int num_b;
      }
      class class_b {
      QString name_b;
      int num_x;
      int numY;
      }

      class class_C {
      QString name_c;
      int num_a;
      int num_b;
      class_a a_array[];
      class_b b_array[];
      }

      In the QML'd version I have:

      class class_C {
      Q_OBJECT

      Q_PROPERTY(QString nodeName READ nodeName)
      Q_PROPERTY(int numA READ numA)
      Q_PROPERTY(int numB READ numB)

      Q_PROPERTY(QList<QObject*> class_a)
      Q_PROPERTY(QList<QObject*> class_b)

      ...
      }

      then in main:

      qmlRegisterUncreatableType<class_a>("Class_a", 1, 0, "Class_a",
      QStringLiteral("CanNodeInfo should not be created in QML."));
      qmlRegisterUncreatableType<class_b>("Class_b", 1, 0, "Class_c",
      QStringLiteral("CanNodeInfo should not be created in QML."));
      qmlRegisterUncreatableType<class_C>("Class_c", 1, 0, "Class_c",
      QStringLiteral("CanNodeInfo should not be created in QML."));

      and:

      engine.rootContext()->setContextProperty(QStringLiteral("class_c_List"), QVariant::fromValue(Cpp2QmlInterfaceClass::getClassC()));

      This has allowed me to access the members of Class c in qml, but (as I have said) I don't see any way to tell qml what the QList<QObject *>'s point to.

      Am I missing something, and if so can someone point me to the relevant documentation? Or is this just something that qml can't do yet (or maybe ever)?

      How have others handled complex nested data structures?

      Regards,
      Greg

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @GregWilsonLindberg said in How to export complex C++ data to qml:

      QList<QObject*> class_a

      Why not

      QList<class_a*> classA;
      

      ?
      Why do you want to use QObject*?
      class_a and class_b do not even inherit from QObject...

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • G Offline
        G Offline
        GregWilsonLindberg
        wrote on last edited by
        #3

        I'm sorry, jsulm, I messed up on my example, class_a & class_b do inherit from Q_OBJECT.

        As to why I don't use the class names directly, I hadn't thought about that, all of the examples and descriptions that I have been able to find show using <QObject *>. Using the class does make more sense, I will try that.

        Thanks,
        Greg

        1 Reply Last reply
        0
        • G Offline
          G Offline
          GregWilsonLindberg
          wrote on last edited by
          #4

          Ok, I changed the definition and all accesses to class * from QObject *. I still can't access the lists.
          The actual Q_PROPERTY now is:
          Q_PROPERTY(QList<class_a *> a_array)

          On the qml side, if I say:

          print(class_c.a_array);

          I get 'a_array undefined'.

          Has anyone had any experience passing complex data types into qml?

          1 Reply Last reply
          0
          • fcarneyF Offline
            fcarneyF Offline
            fcarney
            wrote on last edited by
            #5

            Create a small side project of working code that illustrates this problem and post it here. Its really hard to tell what is wrong without that.

            C++ is a perfectly valid school of magic.

            1 Reply Last reply
            0
            • GrecKoG Offline
              GrecKoG Offline
              GrecKo
              Qt Champions 2018
              wrote on last edited by
              #6

              Qt Quick views can't handle QList<Foo*> even if Foo inherits from QObject.
              You have to expose QList<QObject*> or a proper QAbstractListModel.

              jsulmJ 1 Reply Last reply
              1
              • GrecKoG GrecKo

                Qt Quick views can't handle QList<Foo*> even if Foo inherits from QObject.
                You have to expose QList<QObject*> or a proper QAbstractListModel.

                jsulmJ Offline
                jsulmJ Offline
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @GrecKo So, I was wrong with my suggestion to use QList<Foo*> instead of QList<QObject*>? :-)
                I'm not a QML expert.
                @GregWilsonLindberg looks like my suggestion was wrong, sorry.

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  GregWilsonLindberg
                  wrote on last edited by
                  #8

                  @GrecKo So, the example that I have found has only one list of items in it.

                  The data model that I have has a top level list (this I have working, accessed as an array), and each if these top level elements have several lists.

                  If I implement the top level as an abstract item model then I would need to have several of the data roles return abstract item models. This is the part that I am not understanding.

                  If you look back to my first post, I have an array of the class_C items, and each of those has arrays of class_a & class_b items. I am accessing all of the simple elements of the class_C items, but when it comes to the internal arrays of class_a & class_b and even strings in a QStringList, I can't access any of the sub elements.

                  I created a project that shows what I'm trying to do with the <foo*> notation, while this is incorrect, it does show what is not working.

                  It is available at:
                  https://pastebin.com/mRMwFC0A

                  While it is not surprising that I can't access the structure arrays contained in the top level array, I can't even access the QStringList elements. I just get 0 for the length of the QStringList on the qml side.

                  I will be wanting to use the embedded class arrays as models for other QtQuick elements.

                  Hope this clears up some more of what I'm trying to do. I'm going to do some more research on QAbstractItmeModels.

                  Thanks,
                  Greg

                  1 Reply Last reply
                  0
                  • G Offline
                    G Offline
                    GregWilsonLindberg
                    wrote on last edited by
                    #9

                    In pouring over my code and trying different things I noticed a warning, not an error, that said that I was missing the READ routine for one of my Q_PROPERTY's. And I had included that error in the code example that I put into my first post.

                    I added those in and everything started to work correctly.

                    So, at this point I can access all of the properties in my top level data element and I can also access the properties in the included QList's.

                    Thanks for the suggestions and insights,
                    Greg

                    1 Reply Last reply
                    1

                    • Login

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