从C++创建具有指定属性的QML对象

2022-07-25 00:00:00 qt qml qt-quick c++

从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 ) );

我遇到的问题是,在之后指定SplitVieworientation会导致其内部布局中断。那么,有没有办法用已经指定的orientation来创建SplitView呢?

或者,我可以在单独的文件中创建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();

但出人意料地没有效果。


解决方案

对于仍然对此问题感兴趣的人,在Qt 5(因此Qt 6)中,您还可以使用QQmlContext和QQmlContext::setContextProperty()来设置外部属性(在您的情况下是orientation):

QQmlEngine engine;

QQmlContext *context = new QQmlContext(engine.rootContext());
context->setContextProperty("myCustomOrientation", QVariant::fromValue(orientation));

// you can use a 'myCustomOrientation' property inside Sy_splitView.qml, e.g.
// `orientation: myCustomOrientation`
QQmlComponent splitComp(&engine, QUrl("qrc:/qml/Sy_splitView.qml"));
QObject* splitter = splitComp.create(context);

这应该允许您不摆弄beginCreatecompleteCreate

相关文章