Qt QML:获取发射信号的对象的引用

时间:2017-10-19 20:21:27

标签: qt qml

我的屏幕上有一些可以包含文字的矩形。应通过单击使用此组件的屏幕上的按钮来允许更改这些矩形的文本内容。我遇到的问题是如何在屏幕中知道使用该组件选择了哪个实例。我想通过发出一个信号解决这个问题,该信号传输实例的id作为参考,但似乎这不起作用。怎么可以实现呢?这是我的自定义矩形组件

Rectangle {
     id: root
     width: 50
     height: 50
     color: "#000000"
     anchors.verticalCenter: parent.verticalCenter
     border.color: "#555555"
     property int value: 0
     signal sendId(Item)

Text {
    id: displayed_text
    color: "#ffffff"
    text: root.value
    anchors.horizontalCenter: parent.horizontalCenter
    anchors.verticalCenter: parent.verticalCenter
    horizontalAlignment: Text.AlignHCenter
    verticalAlignment: Text.AlignVCenter
    font.pixelSize: 15
}

MouseArea {
    id: mouseArea
    anchors.fill: parent
    onClicked: {
        root.border.color="#222222"
        root.sendId(root.id)

    }

}

}

这里是其他按钮应该更改自定义组件内容的文件:

            property Item selected: myRectangle
            function changeSelected(value) {
                selected.value=5
            }
            function setSelected(it) {
                root.selected=it
            }

            MyRectangle {
                id: myRectangle
                Component.onCompleted: {
                    myRectangle.sendId.connect(tempNumber.setSelected)
                }
            }
            MyRectangle {
                id: myRectangle1
                Component.onCompleted: {
                    myRectangle1.sendId.connect(tempNumber.setSelected)
                }
            }
            MyRectangle {
                id: myRectangle2
                Component.onCompleted: {
                    myRectangle2.sendId.connect(tempNumber.setSelected)
                }
            }

1 个答案:

答案 0 :(得分:2)

root.sendId(root.id)

id不是常规财产。不要这样使用它。 id的目的是为您提供一个参考,您可以使用它来引用特定对象,所以您真正需要的是:

root.sendId(root)

如果root是您的qml文件根对象,只要sendId(root)没有被遮蔽,sendId也可以工作,根成员可以直接引用,请记住这只适用对于根对象,它不适用于直接或间接父对象但不是root用户的对象。

建议不要将所有内容都放在id - 当你真正需要引用特定对象而不存在其他方法时,只使用id。

您缺少的另一件事是,与JS函数不同,您必须为信号提供一些输入。您仍然可以使用var并传递任何内容,但通常缩小范围会更有效。所以你需要类型和标识符:

signal sendId(Item item)

通过这种方式,您可以访问信号处理程序中的item,这样您就可以避免使用笨拙的命令连接语法,因此您可以简单地:

        MyRectangle {               
            onSendId: tempNumber.setSelected(item)
        }

但是,我说你的设计不是可选的。当您追求通用性和重用时,应该使用信号。您的使用场景更具体,因此可以完全避免使用信号:

// Rect.qml
Rectangle {
  width: 50
  height: 50
  color: manager.selected === this ? "red" : "blue"
  MouseArea {
    anchors.fill: parent
    onClicked: manager.selected = parent
  }
}

// main.qml
Window {
  id: manager

  visible: true
  width: 600
  height: 300

  property Item selected: null

  Row {
    spacing: 2
    Repeater {
      model: 10
      delegate: Rect {}
    }
  }
}

如下例所示,只要可以在对象树下找到对象,就可以通过id直接访问对象。这同样适用于属性,但是id适用于树中的任何对象,属性只有在特定qml文件的根对象中声明时才有效。