Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make QT/QML TextArea scroll to bottom

Tags:

qt

qt5

qml

I'm having this hard time with QT/QML 5.11 over such a simple thing I almost think there's a bug in the library at this point.

I have the following code:

Flickable {
    id: txflick
    anchors.top: title_label.bottom
    anchors.bottom: crect.bottom
    anchors.right: crect.right
    anchors.left: busy_ind.right

    flickableDirection: Flickable.VerticalFlick

    onContentYChanged: console.log("contentY_changed", this.contentY)
    //contentY: txarea.contentHeight - txarea.height
    interactive: false // Has no effect, contentY keeps changing to zero

    TextArea.flickable: TextArea {
        id: txarea

        topPadding: 8
        bottomPadding: 10
        leftPadding: 10
        rightPadding: 10
        readOnly: true
        text: menu_view.pwrcon.text

        onTextChanged: {
            console.log("text changed")
            txflick.contentY = txarea.contentHeight - txflick.height
            console.log("chg", txarea.contentHeight - txflick.height)
            console.log(text)
        }

        onContentHeightChanged: {
            console.log("ctheight = ___", contentHeight, height, txflick.height, txflick.contentHeight)
        }

        font.family: "DejaVu Sans Mono,Ubuntu Sans Mono,Noto Sans Mono"
        font.bold: false
        font.pixelSize:12
        color: "black"
        //verticalAlignment: TextInput.AlignTop
        background: Rectangle { color: "lightgrey"; radius: 2;
            border.width: 1; border.color: "darkgrey" }
    }
}

Basically the TextArea's text is linked to "menu_view.pwrcon.text", which is changed in the Python code (it's a property). When the text changes, I want it to set the flickable to the bottom of the text, so that we see the most recently added lines.

So I do

txflick.contentY = txarea.contentHeight - txflick.height

When the onTextChanged() event is fired. No issues there, I checked the numbers and it's fine (scrolling manually to the number shown with console.log() shows the contentY calculation is correct).

But it seems the component (the flickable), just after I change contentY, changes it alone back to 0 (this behavior happens only after the text height becomes bigger than the fixed height of the flickable). It's so genuinely idiotic I question whether it's a bug or intended.

In other words, right after my calculation, contentY goes back magically to zero without my intervention, which of course breaks the whole thing.

Is there anything to fix this issue?

like image 537
Yannick Avatar asked Oct 27 '22 11:10

Yannick


1 Answers

You can achieve it with Flickable or ScrollView.

changing cursor position to in TextArea will focus on that line automatically.

create a function in the text area and change focus each time text changes. You have to call it manually

 cursorPosition = length-1

or you can directly set property

cursorPosition : length-1 

in TextArea block on each text update.

     ScrollView {
            id: scrollView
            height: parent.height
            width: parent.width
            clip: true
            anchors.fill: parent

            TextArea {
                id: statusTextArea
                Layout.preferredWidth:parent.width
                Layout.fillHeight:  true
                readOnly:           true
                textFormat:         TextEdit.RichText
                text:              "Long Text \n"
                width: parent.width
                height: parent.height
                anchors.fill: parent
                function append(strAdd)
                {
                    statusTextArea.text = statusTextArea.text + strAdd
                    statusTextArea.cursorPosition = statusTextArea.length-1
                }
            }
        }

       Timer {
            running: true
            interval: 1000
            repeat: true
            property int iteration: 0

            onTriggered:{
                statusTextArea.append("Line %1\n".arg(iteration++))
                statusTextArea.append("Line %1\n".arg(iteration++))
             }
        }
like image 53
8-DK Avatar answered Nov 02 '22 23:11

8-DK