2013-10-30 17 views
5

L'istanziazione dinamica di un oggetto QML da C++ è well documented, ma quello che non riesco a trovare è come istanziarlo con valori predefiniti per le sue proprietà.Creare oggetto QML da C++ con proprietà specificate

Ad esempio, sto creando un leggermente modificato SplitView da C++ simili:

QQmlEngine* engine = QtQml::qmlEngine(this); 
QQmlComponent splitComp(engine, QUrl("qrc:/qml/Sy_splitView.qml")); 
QObject* splitter = splitComp.create(); 

splitter->setProperty("orientation", QVariant::fromValue(orientation)); 

Il problema che ho è che specifica il orientation del SplitViewdopo viene creata un'istanza provoca è layout interno rompere . Quindi, c'è un modo per creare lo SplitView con lo orientation già specificato?

In alternativa, è possibile creare sia una versione orizzontale che verticale di SplitView in file separati e creare un'istanza appropriata in fase di esecuzione, ma ciò è meno elegante.

Aggiornamento

ho trovato 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(); 

Ma non ha avuto alcun effetto sorprendentemente.

+0

Scommetto che il problema è nel modo in cui si tenta di assegnare l'enumerazione tramite QVariant (le enumerazioni sono un po 'buggate in QML). Proverò a registrare innanzitutto un semplice tipo basato su QObject e un enum personalizzato e controllare se tutto funziona.[nota anche che a quanto pare si tenta di impostare il genitore due volte, ma questo è minore] – mlvljr

+0

Non lo sapevo riguardo le enumerazioni, quindi grazie ci proverò. E non sto impostando il genitore due volte, ho impostato prima il genitore 'QObject', e poi il genitore visivo QML secondo (se potessi impostare il genitore' QObject' tramite QML, non mi sarei preoccupato del C++ per questo). – cmannett85

+0

Giusto, davvero; invece di impostare il genitore QObject, è possibile impostare la proprietà della memoria (o comunque si chiami) su QmlOwnership, credo (in modo che l'oggetto appena creato venga considerato obsoleto/ref-count dal runtime QML come necessario). A proposito, è necessario che tu abbia impostato il genitore QObject per alcuni motivi diversi dalla gestione della memoria? – mlvljr

risposta

0

Penso che dovresti essere in grado di utilizzare un metodo personalizzato QQmlIncubator e QQmlComponent::create(QQmlIncubator & incubator, QQmlContext * context = 0, QQmlContext * forContext = 0).

In particolare, citando the QQmlIncubator documentation:

vuoto QQmlIncubator :: setInitialState (QObject * object) [virtual protected]

Chiamato dopo che l'oggetto viene creato, ma prima di attacchi di proprietà vengono valutate e , se applicabile, viene chiamato QQmlParserStatus :: componentComplete(). Questo è equivalente al punto tra QQmlComponent :: beginCreate() e QQmlComponent :: endCreate() e può essere utilizzato per assegnare valori iniziali alle proprietà dell'oggetto.

L'implementazione di default non fa nulla.

0

Ho avuto una situazione simile per il mio componente QML. Volevo solo iniziare alcuni oggetti prima di eseguire alcuni collegamenti. In puro QML ho fatto in questo modo:

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

Da C++ ho provato in questo modo:

// 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(); 

ma ho avuto errori di associazione perché modelClass rimane nulla! Dopo aver scavato per un po 'ho trovato la causa. E sembra ragionevole per me. Ho cambiato la mia classe QML!

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

proprietà con valori iniziali subito dopo invocando beginCreate non sono visibili da C++, fino a quando io chiamo completeCreate(). Ma se rimuovo la proprietà del valore iniziale diventa visibile e posso inizializzarla nel codice C++

Problemi correlati