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. Models: QList<QObject*> vs QList<Derived*>
QtWS25 Last Chance

Models: QList<QObject*> vs QList<Derived*>

Scheduled Pinned Locked Moved QML and Qt Quick
17 Posts 3 Posters 5.7k 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.
  • Q Offline
    Q Offline
    qragnar
    wrote on last edited by
    #1

    Hi,

    Fairly simple question: It seems that when I use a GridView with a model of QList<Derived*>, where Derived inherits from QObject, the delegate of my GridView doesn't show anything. If, OTOH I stick with a model QList<QObject*>, it works as expected. (Each QObject pointer points to a Derived).

    Is this normal and expected? Can I use a QList<Derived*> as a model instead, iow. have I just missed something?

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      I'm no QML specialist yet, but did you register your custom type ? Have a look "here":http://qt-project.org/doc/qt-5/qtqml-cppintegration-data.html#qobject-derived-types

      Hope it helps

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • Q Offline
        Q Offline
        qragnar
        wrote on last edited by
        #3

        If by that, you mean:
        @qmlRegisterType<Derived>("MyApp", 1,0, "Derived");@

        then yes, I did.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Also the QList<Derived *> type ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • Q Offline
            Q Offline
            qragnar
            wrote on last edited by
            #5

            I'm not sure I see why that would be required, but I tried it anyway:

            @qmlRegisterType<QList<Derived*> >("MyApp", 1,0, "DerivedList");@

            This causes a compile-error:

            /usr/include/qt5/QtQml/qqml.h:204: error: 'staticMetaObject' is not a member of 'QList<Derived*>'

            I find this even weirder, since /usr/include/qt5 does not exist. I'm using the SailfishSDK and it's under /opt, not /usr. Ah well, I guess the compiler just reports the path incorrectly.

            1 Reply Last reply
            0
            • I Offline
              I Offline
              Ildar
              wrote on last edited by
              #6

              Also, you may using "QQmlListProperty":http://qt-project.org/doc/qt-5/qqmllistproperty.html

              1 Reply Last reply
              0
              • I Offline
                I Offline
                Ildar
                wrote on last edited by
                #7

                [quote author="qragnar" date="1410240330"]I'm not sure I see why that would be required, but I tried it anyway:

                @qmlRegisterType<QList<Derived*> >("MyApp", 1,0, "DerivedList");@

                This causes a compile-error:

                /usr/include/qt5/QtQml/qqml.h:204: error: 'staticMetaObject' is not a member of 'QList<Derived*>'
                [/quote]

                I think this is because QList is not QObject subclass

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Indeed, I've mixed two different things together. Sorry

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • Q Offline
                    Q Offline
                    qragnar
                    wrote on last edited by
                    #9

                    [quote author="Ildar" date="1410240434"]Also, you may using "QQmlListProperty":http://qt-project.org/doc/qt-5/qqmllistproperty.html[/quote]

                    I'm not really sure I understand how this applies to a model. Are you suggesting I simply wrap the QList as a property of a model?

                    1 Reply Last reply
                    0
                    • I Offline
                      I Offline
                      Ildar
                      wrote on last edited by
                      #10

                      Yes, you may create simple wrap for QList<Derived*>
                      I think QQmlListProperty more appropriate way to set collection from C++ to QML. For example:
                      @Q_PROPERTY(QQmlListProperty<Derived> derivedList READ derivedListProperty NOTIFY derivedListChanged)

                      private:
                      QQmlListProperty<Derived> derivedListProperty()
                      {
                      return QQmlListProperty<Derived>(this,
                      NULL,
                      &MyClass::append,
                      &MyClass::count,
                      &MyClass::at,
                      &MyClass::clear);
                      }

                      static void append(QQmlListProperty<Derived> *property, Derived *value)
                      {
                      MyClass myClass = qobject_cast<MyClass>(property->object);

                      if(myClass != NULL)
                      {
                              myClass->add(value);
                      }
                      

                      }

                      static Derived *at(QQmlListProperty<Derivedt> *property, int index)
                      {
                      MyClacc myClass = qobject_cast<MyClass>(property->object);

                      if(myClass != NULL)
                      {
                          return myClass->at(index);
                      }
                      else
                      {
                          return NULL;
                      }
                      

                      }

                      static void clear(QQmlListProperty<Derived> *property)
                      {
                      MyClass myClass = qobject_cast<MyClass>(property->object);

                      if(myClass != NULL)
                      {
                          myClass->clear();
                      }
                      

                      }

                      static int count(QQmlListProperty<Derived> *property)
                      {
                      MyClass myClass = qobject_cast<MyClass>(property->object);

                      if(myClass != NULL)
                      {
                          return myClass->size();
                      }
                      else
                      {
                          return 0;
                      }
                      

                      }
                      @

                      And now in QML you can using myClass.derivedList as simple QML list

                      1 Reply Last reply
                      0
                      • Q Offline
                        Q Offline
                        qragnar
                        wrote on last edited by
                        #11

                        Hmm... Still not sure I'm getting this. I tried your code. Thank you very much for that, btw! However, the GridView doesn't get populated with anything:

                        @GridView {
                        id: buttonGrid
                        anchors.fill: parent
                        model: MyClass.derivedList
                        // ...
                        }@

                        buttonGrid is empty. I've inserted some qDebug() calls and it seems that derivedListProperty() does not even get called...

                        1 Reply Last reply
                        0
                        • I Offline
                          I Offline
                          Ildar
                          wrote on last edited by
                          #12

                          Did you register your custom type?
                          @qmlRegisterType<MyClass>("MyApp", 1,0, "MyClass");@

                          And did you export MyClass instance to QML?
                          @
                          QQmlApplicationEngine *qmlEngine = new QQmlApplicationEngine(this);
                          qmlEngine->rootContext()->setContextProperty("myClass", new MyClass());
                          @
                          Or did you create MyClass instance in QML?
                          @
                          MyClass {
                          id: myClass
                          }
                          GridView {
                          id: buttonGrid
                          anchors.fill: parent
                          model: myClass.derivedList
                          // ...
                          }@

                          1 Reply Last reply
                          0
                          • Q Offline
                            Q Offline
                            qragnar
                            wrote on last edited by
                            #13

                            Yes, I have registered the type using qmlRegisterType. And main.cpp contains the following:

                            @QGuiApplication *app = SailfishApp::application(argc, argv);
                            QQuickView *view = SailfishApp::createView();
                            QQmlContext *ctxt = view->rootContext();
                            
                            MyClass mc;
                            // this is irrelevant here, but included for clarity
                            // it is just to make it possible for mc to use setContectProperty
                            // in this case, it isn't used, though
                            mc.setQmlContext(ctxt);
                            mc.loadData("default");
                            view->setResizeMode(QQuickView::SizeRootObjectToView);
                            ctxt->setContextProperty("MyClass", QVariant::fromValue(&mc));
                            

                            @

                            As you can see, this is really a SailFish app

                            1 Reply Last reply
                            0
                            • I Offline
                              I Offline
                              Ildar
                              wrote on last edited by
                              #14

                              Try ctxt->setContextProperty("myClass", QVariant::fromValue(&mc));
                              and using as model: myClass.derivedList (start with lower letter "m").
                              P.S.
                              MyClass - this is type
                              myClass - this is instance of object

                              1 Reply Last reply
                              0
                              • I Offline
                                I Offline
                                Ildar
                                wrote on last edited by
                                #15

                                And more better set parents to objects. For example:
                                @MyClass *myClass = new MyClass(this);@
                                This is because if object parent is null than QML take ownership of object.

                                1 Reply Last reply
                                0
                                • Q Offline
                                  Q Offline
                                  qragnar
                                  wrote on last edited by
                                  #16

                                  Well, to be precise the type could start with a lower case and the instance name with an upper case, but I suppose using the same name for both could be more problematic.

                                  In any case, it is now working and I can set the model to derivedList. Thanks very much for that suggestion. However, I still have my original problem, which is the reason wanting to use something other than QList<QObject*>. The original problem is that I can't called a method defined in Derived from the Delegate, since QML doesn't know that model is Derived, only QObject.

                                  Update:
                                  Actuallly, I realised after posting this that I can dereference like this:

                                  @onClicked: {
                                  myClass.derivedList[index].doSomeStuff()
                                  myClass.derivedList[index].callAnotherMethod()
                                  }
                                  @

                                  So my original issue is actually solved now. Thanks!

                                  1 Reply Last reply
                                  0
                                  • I Offline
                                    I Offline
                                    Ildar
                                    wrote on last edited by
                                    #17

                                    bq. Well, to be precise the type could start with a lower case and the instance name with an upper case, but I suppose using the same name for both could be more problematic.

                                    Of cource) Simply, I using "Qt coding style":http://qt-project.org/wiki/Qt_Coding_Style

                                    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