2013-08-09 36 views
5

Çalışma zamanı sırasında dinamik olarak oluşturulmuş bileşenlerle doldurulmuş bir kapsayıcım var. Bu elemanların her biri (onları DynamicObject s olarak adlandıralım) dinamik olarak da oluşturulmuş bir alt ağaçlara (Node s) sahiptir. Dahası, Node bileşenleri birbiri içine yerleştirilebilir (ağaç yapısı gibi).QML - bir ataya hitap

Kapsayıcıyı "main_container" olarak ayarlanmış id ve DynamicObject her "dynamic_object" olarak ayarlayın.

İç içe Node öğelerinden herhangi birini main_container adresinden çözmeye çalıştığımda her şey düzgün çalışıyor. Sorun, dynamic_object'u root olandan başka herhangi bir Node adresinden (dynamic_object'un doğrudan soyundan/çocuğundan biri) adreslemeye çalıştığım zamandır. Bu davranışın ardındaki nedeni ne olabilir:

ReferenceError: dynamic_object is not defined

Sorum şu: Bu sonuçlanır? Bu nesnelerin dinamik olarak yaratılmış olması ile bir ilgisi olabilir mi? (Bu, ilk düşüncemden beri her zaman main_container'u ele alabilir ve qml kodunda statik olarak bildirilir).

Kod örnek:

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

Basit bir örnek gösterebiliyor musunuz, böylece yapmaya çalıştığınız şeyi daha iyi anlayabilelim mi? – koopajah

+0

bitti, umarım herhangi bir önemli parçayı unutmadım ve niyetimin ne olduğunu açıklayacağım –

+0

Tüm dinamik nesnelere aynı kimliği veriyor musunuz? – Jay

cevap

4

göre http://qt-project.org/doc/qt-4.8/qdeclarativedynamicobjects.html için (yorumlarda şimdi lütfen içeri eksik bir şey varsa):

  • 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

sorun olduğunu her biri için createComponent() işlevi Sonraki Node, main_container bağlamından çağrıldı, böylece torunların dynamic_object kimliğini çözebilmeleri engellendi.

Node.qml dosyaya iç içe Node s yapmakla sorumlu kodu hareket ettirerek çözüldü (aslında o QML belgeye tarafından ithal bir javascript dosyaya, ancak sonuç aynıdır).