Cant make Instantiator work with QList<QObject*>
-
I am developing for Android and trying to create a Menu with items populated dynamically from a model which is assigned from C++.
QML I use is like this:
@
ApplicationWindow {
menuBar: MenuBar {
Menu {
id: menu
Instantiator {
id: menuInstantiator
MenuItem {
text: model.title || ""
}
onObjectAdded: menu.insertItem(index, object)
onObjectRemoved: menu.removeItem(object)
}
}
}
}
@C++ code is like this:
@
class Info: public QObject
{
Q_OBJECT// Properties for use in QML Q_PROPERTY(QString id READ id) Q_PROPERTY(QString title READ title)
public:
Info(const QString& id, QObject *parent = 0);QString id() const { return m_id; } QString title() const { return m_title; }
private:
QString m_id;
QString m_title;
};...
QList<QObject*> infos;
infos.append(new Info(1));
infos.append(new Info(2));
QObject* menu->setProperty("model", QVariant::fromValue(infos));
...@
The problem is that this is not working - clicking on the menu bar button does not open the menu. As a side effect other menus also stop working.
Similar code with QStringList is working fine. However i want to show one string as item text and pass a different string as item id for triggered event. Thats why I use Info object instead of single string per item
What am I doing wrong?
-
While I didn't test your code, it looks like you are setting the "model" property on the Menu when you should really be setting it on the "menuInstantiator" itself.
See the bottom of http://qt-project.org/doc/qt-5/qml-qtquick-controls-menu.html for an example.
-
Yes, my bad. I changed the code a lot and that code was not the initial code I was expecting to work.
Originally on ApplicationWindow i declared alias property:
@
property alias menuModel: menuInstantiator.model
@and in c++ I called:
@
QObject* root->setProperty("menuModel", QVariant::fromValue(infos));
@However the important point I think is that the same code worked with QStringList, but not with QList<Object*>. Of course expression for MenuItem.text property should be different for QStringList and QList<Object*>, but I would expect only empty or incorrect texts in later case. Now menu is not showing at all
-
I always get problem on passing QList<QObject*> to QML side too.
I think that the problem is due to the fact that QML for some reason cannot properly see a custom QList instantiation.
But, as you notice too, with QStringList everything works fine.
So, my workaround to passing a complex object is to use a QStringList as a list of object IDs and use a slot for getting the corresponding QObject.
Something like that:
@
Instantiator {
id: menuInstantiator
MenuItem {
property InfoObject obj: backend.getInfoObject( modelData )
text: obj.title || ""
}
}
@
where backend is a QObject globally visible to QML with a slot that return a QObject* given an QString id. And the modelData is one of the element of the QStringList that you pass from C++ to QML.Important: InfoObject has to declare the properties via Q_PROPERTY and to registered with qmlRegisterType otherwise QML cannot see it properly.
-
Ah, I was forgetting... PAY ATTENTION TO THE OWNERSHIP OF RETURNING QOBJECT* :
http://qt-project.org/doc/qt-5/qtqml-cppintegration-data.html
It's an important aspect that if taken not seriously into account will crash your app.
-
Thanks for the tips, Gianluca, it helped. Although it would be nicer if QList<QObject*> version worked
-
I think that for get QList<QObject*> work we should file a feature request and to add a derived type QListObjects similar to QStringList and making it usable into QML as QStringList.
-
Well, I am not sure if QListObject is really needed as documentation suggests that QList<QObject*> should work: http://qt-project.org/doc/qt-5/qtquick-modelviewsdata-cppmodels.html. That makes me think that my case is either a bug or I am doing something stupid with the later being more likely as I am really new to QML and Qt.
-
Humm... maybe we are both stupid... because I tried lot in the past and the QList<QObject*> never worked. That's why I developed the workaround I posted.
I'll do some further test. -
I discovered that template into the documentation:
QQmlListPropertyMaybe can be a solution for your problem.
-
Thanks, I'll check this