2013-10-30 2 views
5

C++에서 QML 객체를 동적으로 인스턴스화하는 것은 well documented이지만 실제로 찾을 수없는 것은 속성에 대해 미리 지정된 값으로 인스턴스화하는 방법입니다.지정된 속성을 사용하여 C++에서 QML 객체 만들기

예를 들어,이 같은 ++ A가 약간 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(); 

하지만 놀라 울 정도로 영향을 미치지 아니합니다.

+0

QVariant를 통해 열거 형을 할당하는 방법에 문제가있을 것입니다 (열거 형은 QML에서 다소 버그가 있습니다). 먼저 간단한 QObject 기반 유형 및 사용자 정의 열거 형을 등록하고 모든 것이 제대로 작동하는지 확인하려고합니다.[또한, 당신이 분명히 부모를 두 번 설정하려고 시도했지만, 그게 사소한 것입니다] – mlvljr

+0

열거 형에 대해서는 몰랐습니다. 그래서 그것을 시도해 볼 것입니다. 부모를 두 번 설정하지 않고'QObject' 부모를 먼저 설정 한 다음 QML 시각적 부모를 두 번째로 설정합니다 (QML을 통해 'QObject' 부모를 설정할 수 있다면 C++로 귀찮게하지 않았을 것입니다).). – cmannett85

+0

맞습니다. QObject 부모를 설정하는 대신 QmlOwnership에 메모리 소유권을 설정할 수도 있습니다. (새로 생성 된 객체가 필요에 따라 QML 런타임에 의해 가비지 콜렉션/참조 카운트 될 수 있도록) 믿습니다. Btw, 메모리 관리 이외의 다른 이유로 QObject 부모를 설정해야 할 필요가 있습니까? – mlvljr

답변

0

사용자 정의 QQmlIncubatorQQmlComponent::create(QQmlIncubator & incubator, QQmlContext * context = 0, QQmlContext * forContext = 0) 공장 메서드를 사용할 수 있어야한다고 생각합니다.

공극 QQmlIncubator :: setInitialState (QObject를 * 객체) 가상 보호, 물체가 먼저 생성 된 후에 호출

하지만 속성 바인딩 평가 전에 : the QQmlIncubator documentation 인용 특히

, 적용 가능한 경우, QQmlParserStatus :: componentComplete()가 호출됩니다. 이것은 QQmlComponent :: beginCreate()와 QQmlComponent :: endCreate() 사이의 점과 동일하며, 오브젝트의 특성에 초기 값을 지정하는 데 사용할 수 있습니다.

기본 구현은 아무 것도 수행하지 않습니다.

0

내 자신의 QML 구성 요소에 대해 비슷한 상황이있었습니다. 일부 바인딩을 실행하기 전에 일부 소품을 초기화하고 싶었습니다. C에서

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

는 ++ 내가 그 방법을 시도 : 순수 QML에서 나는 그런 식으로했다

// 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 수업을 변경했습니다. 바로 beginCreate를 호출 한 후 초기 값으로

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

속성 내가 completeCreate를 호출 할 때까지(), C++에서 표시되지 않습니다. 하지만 초기 값 속성을 제거하면 C++ 코드로 초기화 할 수 있습니다.

관련 문제