qt — создание объекта QML из C ++ с указанными свойствами

Динамическое создание объекта QML из C ++ хорошо задокументированы, но что я не могу найти, так это как создать его экземпляр с заранее заданными значениями для его свойств.

Например, я создаю слегка модифицированный SplitView из C ++ вот так:

QQmlEngine* engine = QtQml::qmlEngine( this );
QQmlComponent splitComp( engine, QUrl( "qrc:/qml/Sy_splitView.qml" ) );
QObject* splitter = splitComp.create();

splitter->setProperty( "orientation", QVariant::fromValue( orientation ) );

У меня проблема в том, что указание orientation из SplitView после это создает экземпляр его внутреннего макета, чтобы сломаться. Итак, есть ли способ создания SplitView с orientation уже указано?

В качестве альтернативы я могу создать как горизонтальную, так и вертикальную версию SplitView в отдельных файлах и создайте соответствующий экземпляр во время выполнения — но это менее элегантно.

Обновить

я нашел QQmlComponent::beginCreate(QQmlContext* publicContext):

QQmlEngine* engine = QtQml::qmlEngine( this );
QQmlComponent splitComp( engine, QUrl( "qrc:/qml/Sy_splitView.qml" ) );
QObject* splitter = splitComp.beginCreate( engine->contextForObject( this ) );

splitter->setProperty( "orientation", QVariant::fromValue( orientation ) );
splitter->setParent( parent() );
splitter->setProperty( "parent", QVariant::fromValue( parent() ) );
splitComp.completeCreate();

Но это не имело удивительного эффекта.

6

Решение

Я думаю, что вы должны иметь возможность использовать обычай QQmlIncubator и QQmlComponent::create(QQmlIncubator & incubator, QQmlContext * context = 0, QQmlContext * forContext = 0) заводской метод.

В частности, цитируя QQmlIncubator документация:

void QQmlIncubator :: setInitialState (QObject * object) [виртуальная защита]

Вызывается после первого создания объекта, но до оценки привязок свойств и, если это применимо, вызывается QQmlParserStatus :: componentComplete (). Это эквивалентно точке между QQmlComponent :: beginCreate () и QQmlComponent :: endCreate () и может использоваться для назначения начальных значений свойствам объекта.

Реализация по умолчанию ничего не делает.

0

Другие решения

У меня была похожая ситуация для моего собственного компонента QML. Просто хотел инициировать некоторые реквизиты, прежде чем запускать некоторые привязки. В чистом QML я сделал это так:

var some = component.createObject(this, {'modelClass': my_model});

С C ++ я пробовал так:

// create ui object
auto uiObject = qobject_cast<QQuickItem*>(component.beginCreate(ctx));
// place on ui
uiObject->setParentItem(cont);

// set model properties
classInstance->setView(QVariant::fromValue(uiObject));
classInstance->setPosition(QPointF(x, y));

// set ui object properties
uiObject->setProperty("modelClass", QVariant::fromValue(classInstance.get()));

// finish
component.completeCreate();

но у меня были ошибки привязки, потому что modelClass остается нулевым! Немного покопавшись я нашел причину. И это выглядит разумно для меня. Я изменил свой класс QML!

Item {
id: root
// property var modelClass: null
property var modelClass // just remove : null!
}

Свойства с начальными значениями сразу после вызова beginCreate не видны из C ++, пока я не вызову completeCreate (). Но если я удаляю начальное значение, свойство становится видимым, и я могу инициализировать его в коде C ++

0

По вопросам рекламы [email protected]