带TextArea的QML Flickable:contentY的属性绑定被谁覆盖



我正在制作一个终端小部件。当TextArea.text更新时,我希望Flickable向下滚动到最新的输入。我的代码如下所示。

ColumnLayout {
anchors.fill: parent
Flickable {
id: scroller
clip: true
contentY: contentHeight - height
onContentYChanged: {
console.log("contentY:", contentY)
}
TextArea.flickable: TextArea {
id: textArea
Layout.fillWidth: true
}
Layout.fillWidth: true
Layout.fillHeight: true
}
RowLayout {
id: prompt
Label {
text: " > $ "
}
TextField {
id: textInput
Layout.fillWidth: true
}
}
}

当我运行这个程序时,我看到contentY在被我的绑定设置后立即被覆盖:

qml: contentY: 1498
qml: contentY: 0
qml: contentY: 1517
qml: contentY: 0

我已检查以确保绑定未将其设置为0。我尝试使用export QT_LOGGING_RULES="qt.qml.binding.removal.info=true"调试绑定循环,结果很好。我查看了Flickable的来源,我不认为其中的任何方法是罪魁祸首。

绑定contentY是实现我想要的功能的正确方式吗?为什么我的约束力没有得到尊重

问题是,随着Flickable内部内容的移动,contentY将不断被其覆盖。您不能在其上放置绑定,因为正如您所看到的,它将立即被一个静态值覆盖,该值在用户与flickable交互时更新。

相反,你需要做的是类似的事情

onContentHeightChanged: Qt.callLater(() => contentY = contentHeight - height)

现在,每当文本区域增长时,它都会通过立即赋值来跳转contentY,而不是试图依赖绑定。callLater确保在flickable由于高度更改而自行将contentY重置为0之后发生。

最新更新