1

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

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是做我想做的事情的正确方法吗?为什么我的绑定不被尊重?

4

1 回答 1

3

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

你需要做的是类似

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

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

于 2020-05-08T13:22:06.330 回答