如何解决ListView的itemAtIndex不返回索引处的项目
假设我们有一个模型和两个视图。两个视图使用相同的模型。第二个视图中的项目必须与第一个视图中的相应项目具有相同的宽度。项目之间的宽度不是恒定的。两个视图之间的项目具有相同的索引。
下面的代码产生两个矩形的系列,其索引为文本。 view2中的矩形更窄:
import QtQuick 2.15
Rectangle {
ListView {
id: view1
y: 0
height: 50
width: parent.width
model: ts_model
delegate: Rectangle {
width: 60
height: 50
color: "black"
Text {
text: index
color: "white"
}
}
orientation: Qt.Horizontal
layoutDirection: "LeftToRight"
spacing: 5
}
ListView {
id: view2
y: 100
height: 50
width: parent.width
model: ts_model
delegate: Rectangle {
color: "yellow"
width: 50
height: 50
Text {
text: index
}
}
orientation: Qt.Horizontal
layoutDirection: "LeftToRight"
spacing: 5
}
}
让我们尝试将view1
中的矩形宽度绑定到view2
中的矩形。我希望能够使用view1.itemAtIndex(index)
语法做到这一点:
ListView {
id: view2
y: 100
height: 50
width: parent.width
model: ts_model
delegate: Rectangle {
color: "yellow"
width: view1.itemAtIndex(index).width
height: 50
Text {
text: index
}
}
(... some more code ...)
不幸的是,这不起作用-我得到TypeError: Cannot read property 'width' of null
,有趣的是仅对某些项目失败了:
我确认:
- 两个视图都显示相同数量的元素(相同的模型,没有过滤)
- 两者的索引都从0开始,一直上升到模型中的元素数减去1(如两张图片所示)
- 两个索引都是整数
-
view1
和view2
是同一个父母的孩子,我验证了他们在通过id寻址时可以看到对方
为什么不起作用?
解决方法
这个答案是错误的。它仅适用于所有元素均可见的列表。当代表进入/超出范围时,这会崩溃。
但是,要回答最初的问题-itemAtIndex始终不返回项目的原因是由于构造顺序,即调用该方法时index处的项目未完全构造。
正如JarMan所建议的,问题与view1的子代构造有关。通过一个简单的测试就可以看出这一点。我添加了一条消息来标识创建矩形的顺序:
// view1
delegate: Rectangle {
width: 60
height: 50
color: "black"
Text {
text: index
color: "white"
Component.onCompleted: console.log("Rect1 " + index + " completed")
}
}
// view2
delegate: Rectangle {
color: "yellow"
width: view1.itemAtIndex(index).width
height: 50
Text {
text: index
}
Component.onCompleted: console.log("Rect2 " + index + " completed")
}
哪个会产生以下输出:
qml: Rect2 0 completed
qml: Rect1 0 completed
file:///...: TypeError: Cannot read property 'width' of null
qml: Rect1 1 completed
qml: Rect1 2 completed
qml: Rect1 3 completed
qml: Rect1 4 completed
qml: Rect2 1 completed
qml: Rect2 2 completed
qml: Rect2 3 completed
qml: Rect2 4 completed
qml: Rect2 5 completed
qml: Rect2 6 completed
qml: Rect2 7 completed
qml: Rect2 8 completed
qml: Rect2 9 completed
file:///...: TypeError: Cannot read property 'width' of null
file:///...: TypeError: Cannot read property 'width' of null
file:///...: TypeError: Cannot read property 'width' of null
file:///...: TypeError: Cannot read property 'width' of null
file:///...: TypeError: Cannot read property 'width' of null
qml: Rect1 5 completed
qml: Rect1 6 completed
qml: Rect1 7 completed
很明显,view2
中没有正确创建的矩形是在view1
对应的矩形可用之前创建的。
创建动态对象here
一种解决方法是:1)将第二个视图保存到单独的QML文件中; 2)在完成根项后将其创建为子视图:
view2's QML file
import QtQuick 2.0
ListView {
id: view2
y: 100
height: 50
width: parent.width
model: ts_model
delegate: Rectangle {
color: "yellow"
width: view1.itemAtIndex(index).width
height: 50
Text {
text: index
}
}
orientation: Qt.Horizontal
layoutDirection: "LeftToRight"
spacing: 5
}
main file
import QtQuick 2.15
Rectangle {
id: rect
Component.onCompleted: {
Qt.createComponent("view2.qml").createObject(rect)
}
ListView {
id: view1
y: 0
height: 50
width: parent.width
model: ts_model
delegate: Rectangle {
width: 60
height: 50
color: "black"
Text {
text: index
color: "white"
}
}
orientation: Qt.Horizontal
layoutDirection: "LeftToRight"
spacing: 5
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。