QML:在中继器上调用 itemAt 返回 null
Posted
技术标签:
【中文标题】QML:在中继器上调用 itemAt 返回 null【英文标题】:QML: calling itemAt on Repeater returns null 【发布时间】:2016-09-29 11:03:38 【问题描述】:我的代码:
import QtQuick 2.7
import QtQuick.Window 2.2
Window
visible: true
width: 640
height: 480
Column
Row
Repeater
id: rectRepeater
model: 3
Rectangle
width: 30
height: 30
color: "red"
radius: 10
Row
Repeater
model: 3
Text
text: rectRepeater.itemAt(0).width;
我收到此错误消息:
TypeError: 无法读取 null 的属性“宽度”
我发现this post 说解决方案是像这样使用Component.onCompleted
(只需在Text 对象中插入一个Component.onCompleted
处理程序):
import QtQuick 2.7
import QtQuick.Window 2.2
Window
visible: true
width: 640
height: 480
Column
Row
Repeater
id: rectRepeater
model: 3
Rectangle
width: 30
height: 30
color: "red"
radius: 10
Row
Repeater
model: 3
Text
Component.onCompleted:
text: rectRepeater.itemAt(0).width;
但这失败并出现同样的错误。
有什么想法吗?
【问题讨论】:
【参考方案1】:当您调用itemAt(0)
时,rectRepeater
项目不会退出。
当rectRepeater
被实例化时,你应该调用itemAt
。
Window
visible: true
width: 640
height: 480
Column
Row
Repeater
id: rectRepeater
model: 3
Rectangle
width: 30
height: 30
color: "red"
radius: 10
Row
Repeater
id: textrep
model: 3
Text
Component.onCompleted:
//Here all object are instantiated
for (var i = 0; i< textrep.count; i++)
textrep.itemAt(i).text = rectRepeater.itemAt(0).width
【讨论】:
谢谢,这行得通。所以关键是等待onCompleted
。但是我自己的代码也在等待那个信号! (请参阅我的问题中的第二个代码 sn-p。)那么有什么区别?
在您的代码中,onCompleted
信号仅适用于 Text
组件。所以它会在文本组件被实例化时发出。在我的代码中,onCompleted
应用于 Column
组件,当列组件和所有他的孩子被实例化时,它会发出。【参考方案2】:
我会选择条件绑定
Text
text: rectRepeater.count > 0 ? rectRepeater.itemAt(0).width : 0;
一旦 rectRepeater 实际上创建了至少一个委托,就会读取该委托的值。 即使 rectRepeater 的模型在某个时候再次变为空,或者索引 0 处的项目改变了它的宽度,这仍然有效
【讨论】:
酷,谢谢!这在某些方面比onCompleted
解决方案更优雅。你写了一些原因,它也让我在它影响的元素中拥有绑定代码,这非常好。一个缺点是它有点冗长(尤其是绑定不支持多语句绑定功能)并且很难理解它的目的,需要注释。但总而言之,这是我将使用的解决方案。请注意,Konstantin T. 的回答还允许通过分配 Qt.binding(...)
表达式对宽度进行动态绑定。
嗯,我刚刚测试了多语句绑定函数,结果证明它们有效!这使您的解决方案更具吸引力。
推测,未验证:这可能最终会设置文本 3 次(在此示例中),因为重复次数从 0 增加到 3。这里基本上无关紧要,但在其他一些情况下它可能足够重。
当计数发生变化时,绑定表达式将再次被计算,但文本属性的设置器将意识到没有变化,因此不会对可视化或使用该文本的任何绑定进行不必要的更新请求属性作为其输入之一
不确定多语句绑定是什么意思,但绑定表达式基本上是一个函数,可以任意复杂(并不是说这一定是个好主意)。您还可以在 rectRepeater 中定义一个函数来执行此操作并将该函数用作绑定表达式:text: rectRepeater.firstRectWidth()
以上是关于QML:在中继器上调用 itemAt 返回 null的主要内容,如果未能解决你的问题,请参考以下文章
QTableWidgetItem.itemAt(pos) 在 contextMenu 请求时总是返回 0