How to access a QML's attached property from C++
-
E.g. my simple qml is that:
// main.qml import QtQuick 2.0 import QtQuick.Layouts 1.3 RowLayout { width: 100 height: 100 Rectangle { objectName: "myRect" color:"red" Layout.fillWidth: true Layout.fillHeight: true Layout.maximumWidth: 55 } }Normally I can easily access to a normal property of my qml item (e.g. "color") like that:
// main.cpp QQuickView view; view.setSource(QUrl(QStringLiteral("qrc:/main.qml"))); view.show(); QQuickItem* rootItem = view.rootObject(); QQuickItem* rectangle = rootItem->findChild<QQuickItem*>("myRect"); qDebug() << rectangle->property("color"); // Worked!But the same thing is not working on attached properties (e.g. "Layout.maximumWidth") like that:
// main.cpp QQuickView view; view.setSource(QUrl(QStringLiteral("qrc:/main.qml"))); view.show(); QQuickItem* rootItem = view.rootObject(); QQuickItem* rectangle = rootItem->findChild<QQuickItem*>("myRect"); qDebug() << rectangle->property("Layout.maximumWidth"); // Not worked!Plus, I've tired
QQmlContext's contextProperty() function, andQQmlProperty's read() function withQQmlProperty(QObject *obj, const QString &name, QQmlContext *ctxt)as referred here and these are not working also, e.g:// main.cpp QQuickView view; view.setSource(QUrl(QStringLiteral("qrc:/main.qml"))); view.show(); QQuickItem* rootItem = view.rootObject(); QQuickItem* rectangle = rootItem->findChild<QQuickItem*>("myRect"); QQmlProperty property(rectangle, "Layout.maximumWidth",view.rootContext()); qDebug() << property.read(); // Not worked!The console output I got everytime:
QML debugging is enabled. Only use this in a safe environment. QVariant(Invalid)On the other hand I've found an another way to access attached properties (source):
template<typename T> QObject *qmlAttachedPropertiesObject(const QObject *attachee, bool create = true)But this function only work with user defined
typename Ts like that example code. Because I've no access to the type of LayoutQQuickLayoutAttached, it's private (source).In short, even Qt documentation says (source):
As QML uses Qt's meta-type system all of the existing QMetaObject classes can be used to introspect and interact with objects created by QML. However, some of the new features provided by QML - such as type safety and attached properties - are most easily used through the QQmlProperty class that simplifies some of their natural complexity.And says (source):
Creating a QQmlProperty without a context will render some properties - like attached properties - inaccessible.So according to documentations I should be able to read attached properties from C++ already, but I can't.
-
I've found a way to do it, but It's not actually efficient. Please share if you know better. Thanks.
QQuickView view; view.setSource(QStringLiteral("qrc:/main.qml")); view.show(); QQuickItem* item = view.rootObject()->findChild<QQuickItem*>("myRect"); for(auto obj : item->children()) if (0 == QString::compare(obj->metaObject()->className(), "QQuickLayoutAttached")) { qDebug() << obj->property("maximumWidth"); break; }