Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Update: Forum Guidelines & Code of Conduct


    Qt World Summit: Early-Bird Tickets

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

    QML and Qt Quick
    3
    17
    4970
    Loading More Posts
    • 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
      qragnar last edited by

      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 Reply Quote 0
      • SGaist
        SGaist Lifetime Qt Champion last edited by

        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 Reply Quote 0
        • Q
          qragnar last edited by

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

          then yes, I did.

          1 Reply Last reply Reply Quote 0
          • SGaist
            SGaist Lifetime Qt Champion last edited by

            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 Reply Quote 0
            • Q
              qragnar last edited by

              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 Reply Quote 0
              • I
                Ildar last edited by

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

                1 Reply Last reply Reply Quote 0
                • I
                  Ildar last edited by

                  [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 Reply Quote 0
                  • SGaist
                    SGaist Lifetime Qt Champion last edited by

                    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 Reply Quote 0
                    • Q
                      qragnar last edited by

                      [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 Reply Quote 0
                      • I
                        Ildar last edited by

                        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 Reply Quote 0
                        • Q
                          qragnar last edited by

                          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 Reply Quote 0
                          • I
                            Ildar last edited by

                            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 Reply Quote 0
                            • Q
                              qragnar last edited by

                              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 Reply Quote 0
                              • I
                                Ildar last edited by

                                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 Reply Quote 0
                                • I
                                  Ildar last edited by

                                  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 Reply Quote 0
                                  • Q
                                    qragnar last edited by

                                    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 Reply Quote 0
                                    • I
                                      Ildar last edited by

                                      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 Reply Quote 0
                                      • First post
                                        Last post