ListView.view 在 ListView 的委托中始终为 null

ListView.view is always null in ListView's delegate

设置

我有一个带有一些通用模型和 myDelegate 组件的 ListView

ListView {
    id: myListView
    delegate: myDelegate
    ...
}

myDelegate组件中,我想设置ListViewcurrentItem。我目前是这样做的:

Component {
    id: myDelegate
    ...
    MouseArea {
        onClicked: myListView.currentIndex = model.index
    }
}

一切正常。

问题

众所周知,在委托中使用 ListViewid 是不好的做法,因为可能有多个 ListView 使用同一个委托组件。因此,应该使用附加的 ListView.view 属性。

但是如果我像这样更改委托的代码:

Component {
    id: myDelegate
    ...
    MouseArea {
        onClicked: ListView.view.currentIndex = model.index
    }
}

我得到一个 TypeError: Value is null and could not be converted to an object.

随着下面的console.logs,我发现ListView.view总是null。我不明白为什么。在 ListView 上设置 currentIndex 本身也会失败。

onClicked: {
    console.log("ListView:", ListView)
    console.log("ListView.view:", ListView.view)
    console.log("ListView.currentIndex:", ListView.currentIndex)
}
...
qml: ListView: QQuickListViewAttached(0x6db0b30)
qml: ListView.view: null
qml: ListView.currentIndex: undefined

最小的可重现示例

Qt v6.2.1
Qt Creator 中的空 Qt Quick 项目
main.qml:

import QtQuick
import QtQuick.Window

Window {
    width: 150
    height: 350
    visible: true

    Component {
        id: myDelegate

        Rectangle {
            color: ListView.isCurrentItem ? "pink" : "lightblue"
            implicitWidth: 150
            implicitHeight: 50

            MouseArea {
                anchors.fill: parent
                onClicked: {
                    ListView.view.currentIndex = model.index
                    console.log("ListView", ListView)
                    console.log("ListView.view", ListView.view)
                }
            }

            Text {
                anchors.centerIn: parent
                text: model.index
            }
        }
    }

    ListView {
        id: myListView
        anchors.fill: parent
        spacing: 2
        model: 6
        delegate: myDelegate
    }
}

附加属性设置在委托的根目录中,因此如果您想从子项访问,则必须使用根目录作为参考:

    Component {
        id: myDelegate

        Rectangle {
            id: root_delegate // <---

            color: ListView.isCurrentItem ? "pink" : "lightblue"
            implicitWidth: 150
            implicitHeight: 50

            MouseArea {
                anchors.fill: parent
                onClicked: {
                    root_delegate.ListView.view.currentIndex = model.index;
                    console.log("ListView", root_delegate.ListView);
                    console.log("ListView.view", root_delegate.ListView.view);
                }
            }

            Text {
                anchors.centerIn: parent
                text: model.index
            }

        }

    }