【问题标题】:Qt QML: Get reference to object emitting a signalQt QML:获取对发出信号的对象的引用
【发布时间】:2017-10-20 06:05:25
【问题描述】:

我有一个带有一些可以包含文本的矩形的屏幕。应该允许这些矩形的文本内容通过单击使用该组件的屏幕中的按钮来更改。我遇到的问题是如何在使用此组件的屏幕中知道选择了哪个实例。我想过通过发出一个信号来解决这个问题,该信号将实例的 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)
                }
            }

【问题讨论】:

    标签: qt qml


    【解决方案1】:
    root.sendId(root.id)
    

    id 不是常规属性。不要这样使用它。 id 的目的是为您提供一个引用,您可以使用它引用特定对象,因此您真正需要的是:

    root.sendId(root)
    

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

    建议的做法是不要给所有东西一个 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 文件的根对象中声明时才有效。

    【讨论】:

      猜你喜欢
      • 2011-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多