【问题标题】:QML - addressing an ancestorQML - 寻址祖先
【发布时间】:2013-08-09 09:47:10
【问题描述】:

我有一个容器,它在运行时被动态创建的组件填充。这些元素中的每一个(我们称它们为DynamicObjects)都有一个子元素树(Nodes),也是动态创建的。更重要的是,Node 组件可以相互嵌套(就像树结构一样)。

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

每当我尝试从任何嵌套的Node 元素中处理main_container 时,它都可以正常工作。问题是当我尝试从除根之外的任何Node(即dynamic_object 的直接后代/子代)中处理dynamic_object 时。结果是:

ReferenceError: 未定义动态对象

我的问题是:这种行为背后的原因可能是什么?它与这些对象是动态创建的事实有关吗? (这是我的第一个想法,因为我总是可以处理 main_container 并且它是在 qml 代码中静态声明的)。

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

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

【问题讨论】:

  • 你能举个简单的例子让我们更好地理解你想要做什么吗?
  • 完成了,希望我没有忘记任何关键部分,它会阐明我的意图
  • 你是否给所有的动态对象相同的id?
  • 是的。我可以尝试为动态对象分配不同的 ID,但这可能需要添加一个只读属性,该属性将设置为动态对象本身(以便它的组件能够使用它的属性)。我仍然认为这不是问题的根源,因为每个Node 都应该能够通过dynamic_object id 看到它的祖先DynamicObject。至少这是我的猜测。如果这就是这一切背后的原因,那么我猜根 Nodes 也不应该能够引用父 DynamicObject

标签: qt qml qt-quick qtquick2


【解决方案1】:

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

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

问题是每个后续NodecreateComponent() 函数是从main_container 的上下文中调用的,因此阻止了后代能够解析dynamic_object id。

通过将负责创建嵌套Nodes 的代码移至Node.qml 文件(实际上是该qml 文档导入的javascript 文件,但结果相同)来解决。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-25
    • 1970-01-01
    • 1970-01-01
    • 2013-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多