2013-08-09 10 views
5

Ich habe einen Container, der zur Laufzeit mit dynamisch erstellten Komponenten gefüllt wird. Jedes dieser Elemente (nennen wir sie DynamicObject s) hat einen Baum von Unterelementen (Node s), auch dynamisch erstellt. Darüber hinaus können die Komponenten Node ineinander verschachtelt werden (wie eine Baumstruktur).QML - Adressierung eines Vorfahren

Lassen Sie den Container den id Parameter auf "main_container" setzen und setzen Sie ihn alle DynamicObject auf "dynamic_object".

Immer wenn ich versuche, die main_container von einem der verschachtelten Node Elemente zu adressieren, funktioniert alles in Ordnung. Das Problem ist, wenn ich versuche, die dynamic_object von jedem Node anderen als der Wurzel zu adressieren (der eine, der der direkte Nachfahre/Kind des dynamic_object ist). Es ergibt sich:

ReferenceError: dynamic_object is not defined

Meine Frage ist:, was sich hinter diesem Verhalten die Ursache sein könnte? Kann es etwas damit zu tun haben, dass diese Objekte dynamisch erstellt werden? (das war mein erster Gedanke, da ich immer die main_container ansprechen kann und sie im qml-Code statisch deklariert ist).

Code-Beispiel: (wenn es etwas gibt, treten Sie mit mir jetzt in den Kommentaren lassen fehlt)

// 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

Können Sie ein einfaches Beispiel zeigen, damit wir besser verstehen, was Sie zu tun versuchen? – koopajah

+0

getan, hoffe, ich habe keinen entscheidenden Teil vergessen, und es wird klarstellen, was meine Absichten sind –

+0

Geben Sie allen dynamischen Objekten die gleiche ID? – Jay

Antwort

4

Nach 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

Das Problem war, dass die createComponent() Funktion für jede der nachfolgende Node wurde aus dem Kontext des main_container aufgerufen, wodurch verhindert wird, dass die Nachkommen die dynamic_object ID auflösen können.

Gelöst, indem Sie den Code für das Erstellen der verschachtelten Node s auf die Node.qml Datei (eigentlich auf eine Javascript-Datei von diesem Qml-Dokument importiert, aber das Ergebnis ist das gleiche).