Как получить доступ к вложенному объекту QML из С++?
Вот пример воспроизводимости:
main.qml
import QtQuick 2.0
Item {
id : root
width: 360
height: 360
Text {
id : t1
text: qsTr("Hello World")
property int someNumber: 1000
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
}
main.cpp
#include <QtGui/QGuiApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QQmlProperty>
#include <QDebug>
#include "qtquick2applicationviewer.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/untitled/main.qml"));
viewer.showExpanded();
QQmlEngine engine;
QQmlComponent component(&engine, "qml/untitled/main.qml");
QObject *object = component.create();
qDebug() << "Property value:" << QQmlProperty::read(object, "root.t1.someNumber").toInt();
return app.exec();
}
Я хочу получить доступ к property
somenumber text
QML Item
.
Вышеуказанный метод не дает желаемого результата.
Как это сделать?
Ответы
Ответ 1
У вас есть два способа (по крайней мере) выполнить это в зависимости от ваших личных предпочтений.
Расширение кода QML
Вы можете добавить псевдоним свойства к корневому элементу следующим образом:
import QtQuick 2.0
Item {
id : root
width: 360
height: 360
property alias mySomeNumber: t1.someNumber // This is the addition
Text {
id : t1
text: qsTr("Hello World")
property int someNumber: 1000
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
}
Расширение кода С++
Поскольку элементы QML QObject
, вы также можете явно искать дочерние элементы, как и в иерархии С++ QObject
. Код будет примерно таким:
#include <QtGui/QGuiApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QQmlProperty>
#include <QDebug>
#include "qtquick2applicationviewer.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/untitled/main.qml"));
viewer.showExpanded();
QQmlEngine engine;
QQmlComponent component(&engine, "qml/untitled/main.qml");
QObject *object = component.create();
// This line is added
QObject *childObject = object->findChild<QObject*>("SomeNumberText");
// The following line is modified respectively
qDebug() << "Property value:" << QQmlProperty::read(childObject, "someNumber").toInt();
return app.exec();
}
Однако это означает, что вам нужно будет добавить строку objectName: "SomeNumberText"
в свой текстовый элемент Text в файле qml.
Ответ 2
Здесь вы можете найти рекурсивный метод для поиска элемента QML с помощью objectName
и начиная с QQmlApplicationEngine::rootObjects()
:
////
static QQuickItem* FindItemByName(QList<QObject*> nodes, const QString& name)
{
for(int i = 0; i < nodes.size(); i++){
// search for node
if (nodes.at(i) && nodes.at(i)->objectName() == name){
return dynamic_cast<QQuickItem*>(nodes.at(i));
}
// search in children
else if (nodes.at(i) && nodes.at(i)->children().size() > 0){
QQuickItem* item = FindItemByName(nodes.at(i)->children(), name);
if (item)
return item;
}
}
// not found
return NULL;
}
///
static QQuickItem* FindItemByName(QQmlApplicationEngine* engine, const QString& name)
{
return FindItemByName(engine->rootObjects(), name);
}
Ответ 3
Каков прецедент для этого? Возможно, было бы лучше просто обработать структуру или объект [text, someNumber] в качестве модели. Тогда вам нужно всего лишь найти объект модели. Или вы можете создать объект модели на стороне С++ и установить его в контексте QML. Вы можете получить доступ к модели и ее вложенным свойствам в QML:
Text {
text: model.text
property int someNumber: model.someNumber
}