Models: QList<QObject*> vs QList<Derived*>
-
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
-
Also the QList<Derived *> type ?
-
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.
-
Also, you may using "QQmlListProperty":http://qt-project.org/doc/qt-5/qqmllistproperty.html
-
[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
-
Indeed, I've mixed two different things together. Sorry
-
[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?
-
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
-
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...
-
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
// ...
}@ -
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
-
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!
-
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