2013-08-09 8 views
5

Mam kontener, który jest wypełniany dynamicznie tworzonymi komponentami podczas wykonywania. Każdy z tych elementów (nazwijmy je: DynamicObject s) ma drzewo podelementów (Node s), również tworzone dynamicznie. Co więcej, komponenty Node mogą być zagnieżdżane wewnątrz siebie (jak struktura drzewa).QML - adresowanie przodka

Niech pojemnik ma ustawiony parametr id na "main_container", a każde ustawienie ma wartość "dynamic_object".

Ilekroć próbuję adres main_container z dowolnego z zagnieżdżonych elementów Node wszystko działa dobrze. Problem polega na tym, że próbuję adresować dynamic_object z dowolnego innego Node niż root (ten będący bezpośrednim potomkiem/dzieckiem dynamic_object). Powoduje to:

ReferenceError: dynamic_object is not defined

Moje pytanie brzmi:, co może być przyczyną tego zachowania za? Czy może mieć coś wspólnego z tym, że obiekty są dynamicznie tworzone? (to była moja pierwsza myśl, ponieważ zawsze mogę adresować main_container i jest statycznie zadeklarowana w kodzie qml).

przykładowy kod: (jeśli jest coś brakuje daj mi teraz w komentarzach)

// Container.qml 

import "container_logic.js" as Logic 

Rectangle { 
    id: main_container 

    Keys.onTabPressed: { 
    Logic.createComponent("DynamicObject.qml", {/* some parameters */}); 
    var dynamic_object = Logic.object; 

    Logic.createComponent("Node.qml",{labelText: "asdefg"}, undefined, dynamic_object) 
    var asdefg = Logic.object; 
    Logic.createComponent("Node.qml",{labelText: "tree A"}, undefined, dynamic_object) 
    var tree_a = Logic.object; 

    Logic.createComponent("Node.qml",{labelText: "a"}, undefined, asdefg) 
    var a = Logic.object; 
    Logic.createComponent("Node.qml",{labelText: "s"}, undefined, asdefg) 
    var s = Logic.object; 

    asdefg.subnodes = [a, s] 

    Logic.createComponent("Node.qml",{labelText: "tree B", isInput: false}, undefined, dynamic_object) 
    var tree_b = Logic.object; 
    Logic.createComponent("Node.qml",{labelText: "xyz", isInput: false}, undefined, dynamic_object) 
    var xyz = Logic.object; 

    Logic.createComponent("Node.qml",{labelText: "x", isInput: false}, undefined, xyz) 
    var x = Logic.object; 
    Logic.createComponent("Node.qml",{labelText: "y", isInput: false}, undefined, xyz) 
    var y = Logic.object; 
    Logic.createComponent("Node.qml",{labelText: "z", isInput: false}, undefined, xyz) 
    var z = Logic.object; 

    xyz.subnodes = [x,y,z] 

    dynamic_object.treeLeft = [asdefg, tree_a] 
    dynamic_object.treeRight = [tree_b, xyz] 
    } 
} 

// DynamicObject.qml 

Rectangle { 
    id: dynamic_object 

    property alias treeLeft : tree_left.subnodes 
    property alias treeRight: tree_right.subnodes 

    Rectangle { 
    id: content_area 

    Node { 
     id: tree_left 

     labelText: "left" 

     anchors.left: parent.left 
    } 

    Node { 
     id: tree_right 

     labelText: "right" 

     anchors.right: parent.right 
    } 
    } 
} 

// Node.qml 

ColumnLayout { 
    id: node 

    default property alias subnodes: subnodes_area.data 
    property alias labelText: label.text 

    Rectangle { 
    id: header_area 

    Text { 
     id: label 
    } 

    MouseArea { 
     id: mouse_area 

     anchors.fill: parent 

     hoverEnabled: true 
     onHoveredChanged: { 
     console.debug(main_container) // works fine 
     console.debug(dynamic_object) // **generates the error for all nodes but the root one** 
     } 
    } 
    } 

    ColumnLayout { 
    id: subnodes_area 

    anchors.top: header_area.bottom 
    } 
} 

// container_logic 

var component = null 
var owner = main_container 
var object = null 
var data = null 

function createComponent(type, info, callback, container) { 
    callback = callback || finishComponent 
    owner = container || main_container 

    if(component != null) { 
    console.log("Error: a component is being loaded at this time"); 
    return; 
    } 

    component = Qt.createComponent(type) 
    data = info 

    if(component.status === Component.Ready) { 
    callback() 
    } else if(component.status === Component.Loading) { 
    component.statusChanged.connect(callback) 
    } else { 
    console.log("Error loading component:", component.errorString()) 
    } 
} 

function finishComponent() { 
    if(component.status === Component.Ready) { 
    object = component.createObject(owner, data) 
    if(object === null) { 
     console.log("Error creating object") 
    } 
    } else if(component.status === Component.Error) { 
    console.log("Error loading component:", component.errorString()) 
    } 
    resetData() 
} 

function resetData() { 
    component = null; 
    data = null; 
} 
+0

Czy możesz pokazać prosty przykład, abyśmy mogli lepiej zrozumieć, co próbujesz zrobić? – koopajah

+0

zrobione, mam nadzieję, że nie zapomniałem żadnej istotnej części i że wyjaśnię, jakie są moje intencje –

+0

Czy nadajesz wszystkim dynamicznym obiektom ten sam identyfikator? – Jay

Odpowiedz

4

Według http://qt-project.org/doc/qt-4.8/qdeclarativedynamicobjects.html:

  • If Qt.createComponent() is used, the creation context is the QDeclarativeContext in which this method is called
  • If a Component{} item is defined and createObject() is called on that item, the creation context is the context in which the Component is defined

Problem polegał na tym, że funkcja createComponent() dla każdego następnie Node został wywołany z kontekstu main_container, uniemożliwiając w ten sposób potomkom możliwość rozstrzygnięcia identyfikatora dynamic_object.

Rozwiązano, przesuwając kod odpowiedzialny za utworzenie zagnieżdżonego Node s do pliku Node.qml (w rzeczywistości do pliku javascript zaimportowanego przez ten dokument qml, ale wynik jest taki sam).