QML - 解决祖先问题

时间:2013-08-09 09:47:10

标签: qt qml qt-quick qtquick2

我有一个容器,它在运行时被动态创建的组件填充。每个元素(让我们称之为DynamicObject)都有一个子元素树(Node s),也是动态创建的。更重要的是,Node组件可以彼此嵌套(如树结构)。

让容器将id参数设置为"main_container",并将每个DynamicObject设置为"dynamic_object"

每当我尝试从任何嵌套的main_container元素中解决Node时,一切正常。问题是当我尝试从根dynamic_object以外的任何Node处理dynamic_object时(main_container的直接后代/子项)。结果是:

  

ReferenceError:未定义dynamic_object

我的问题是:这种行为背后可能是什么原因?它可以与这些对象动态创建的事实有关吗? (这是我的第一个想法,因为我总能解决// 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; } 并且它在qml代码中被静态声明。)

代码示例:(如果有任何遗漏,请在评论中告诉我)

{{1}}

1 个答案:

答案 0 :(得分:4)

根据http://qt-project.org/doc/qt-4.8/qdeclarativedynamicobjects.html

  
      
  • 如果使用Qt.createComponent(),则创建上下文是调用此方法的QDeclarativeContext
  •   
  • 如果定义了Component {}项并且在该项上调用了createObject(),则创建上下文是定义Component的上下文
  •   

问题是每个后续createComponent()的{​​{1}}函数是从Node的上下文调用的,因此阻止了后代能够解析main_container标识。

通过将负责创建嵌套dynamic_object的代码移动到Node文件(实际上是由该qml文档导入的javascript文件,但结果相同)解决了这个问题。