QML Flickable с TextArea: привязка свойств для contentY перезаписывается - кем? - PullRequest
0 голосов
/ 08 мая 2020

Я делаю виджет терминала. Я хочу, чтобы 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. Я попытался отладить привязку l oop с помощью export QT_LOGGING_RULES="qt.qml.binding.removal.info=true", которая вышла чистой. Я просмотрел исходный код Flickable и не думаю, что виноват какой-либо из методов.

Является ли привязка contentY правильным способом делать то, что я хочу? Почему моя привязка не соблюдается?

1 Ответ

2 голосов
/ 08 мая 2020

Проблема в том, что contentY будет постоянно перезаписываться Flickable, когда содержимое внутри него перемещается. Вы не можете привязать его, потому что, как видите, он будет немедленно перезаписан значением stati c, которое обновляется по мере взаимодействия пользователя с flickable.

Вместо этого вам нужно сделать что-то вроде

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

Теперь, когда текстовая область растет, она будет перескакивать через contentY посредством немедленного присваивания вместо того, чтобы полагаться на привязку. CallLater гарантирует, что это произойдет после того, как flickable самостоятельно сбрасывает contentY в 0 из-за изменения высоты.

...