从C ++动态实例化QML对象是well documented,但我找不到的是如何使用为其属性预先指定的值来实例化它。
例如,我正在用C ++创建一个稍微修改过的SplitView
:
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();
但它没有令人惊讶的效果。
答案 0 :(得分:0)
我认为您应该可以使用自定义QQmlIncubator
和QQmlComponent::create(QQmlIncubator & incubator, QQmlContext * context = 0, QQmlContext * forContext = 0)
工厂方法。
特别引用the QQmlIncubator
documentation:
void QQmlIncubator :: setInitialState(QObject * object)[虚拟保护]
在首次创建对象之后调用,但在评估属性绑定之前调用,如果适用,则调用QQmlParserStatus :: componentComplete()。这相当于QQmlComponent :: beginCreate()和QQmlComponent :: endCreate()之间的点,可用于为对象的属性分配初始值。
默认实现不执行任何操作。
答案 1 :(得分: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仍为null!经过一段时间的挖掘后,我找到了原因。对我来说这看起来很合理。我改变了我的QML课程!
Item {
id: root
// property var modelClass: null
property var modelClass // just remove : null!
}
在调用beginCreate()之后,在调用beginCreate之后,具有初始值的属性在C ++中是不可见的。但是,如果我删除初始值属性变得可见,我可以在C ++代码中初始化它