【发布时间】:2013-11-10 14:22:33
【问题描述】:
从 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 ) );
我遇到的问题是,指定SplitView 的orientation 在实例化后会导致其内部布局中断。那么,有没有办法在已经指定 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();
但出乎意料的没有效果。
【问题讨论】:
-
我敢打赌,问题在于您如何尝试通过 QVariant 分配枚举(枚举在 QML 中有些错误)。我会尝试首先注册一个简单的基于 QObject 的类型和一个自定义枚举,然后检查整个事情是否有效。 [另请注意,您显然尝试设置 parent 两次,但这是次要的]
-
我对枚举一无所知,所以谢谢,我会试试的。而且我没有设置父级两次,我首先设置
QObject父级,然后是QML视觉父级(如果我可以通过QML设置QObject父级,我根本不会为此烦恼C++ )。 -
没错,确实;我相信,您可以将内存所有权(或无论如何调用)设置为 QmlOwnership,而不是设置 QObject 父级(以便 QML 运行时根据需要对新创建的对象进行垃圾收集/引用计数)。顺便说一句,您是否出于内存管理以外的某些原因特别需要设置 QObject 父级?
-
用于内存管理。每个
SplitView包含两个自定义OSG 视口,每个视口又可以无限分割(如Qt Creator 的文本编辑器窗格),形成一棵树。因此,当我删除特定的拆分器时,它会适当地删除所有子级。我会看看在 QML 方面拥有所有权,它可能会简化事情 - 谢谢!