2013-10-30 99 views
5

從C++動態實例化一個QML對象是well documented,但我找不到如何使用它的屬性的預先指定的值來實例化它。從C++創建具有指定屬性的QML對象

例如,我創建一個選自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 parent,你可以將內存所有權(或稱爲QmlOwnership)設置爲QmlOwnership,我相信(如果需要,新創建的對象將由QML運行時進行垃圾收集/重新計數)。順便說一下,你是否因爲內存管理以外的某些原因而特別需要設置QObject父級? – mlvljr

回答

0

我認爲你應該可以使用自定義QQmlIncubatorQQmlComponent::create(QQmlIncubator & incubator, QQmlContext * context = 0, QQmlContext * forContext = 0)工廠方法。

特別是,從the QQmlIncubator documentation引述:

空隙QQmlIncubator :: setInitialState(QObject的*對象)[虛保護]

在首次創建對象後調用,但屬性綁定進行評估之前和,如果適用的話,調用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! 
} 

直到我調用completeCreate(),調用beginCreate後的初始值的屬性才從C++中看到。但是,如果我刪除初始值屬性變得可見,我可以初始化它在C++代碼

相關問題