TextArea does not automatically scroll



  • Hello,

    I have some problems with TextArea.
    My goal is to program a Code Editor, but I have some problems adding Linenumbers next to the textArea.

    This is my attempt:

    Pane {
      RowLayout {
        anchors.fill: parent
        spacing: 0
    
        ColumnLayout {
          id: lineNumbers
          Repeater {
            id: lineNumberRepeater
            model: editor.lineCount
            Layout.fillHeight: true
            Text {
              text: index + 1
              color: 'lightgray'
              font.pointSize: editor.font.pointSize
            }
          }
        }
    
        Flickable {
          id: flickable
          Layout.fillHeight: true
          Layout.fillWidth: true
          TextArea.flickable: TextArea {
            id: editor
            focus: true
            persistentSelection: true
            selectByMouse: true
            textMargin: 10
            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
    
            Keys.onPressed: {
              if(event.key === Qt.Key_PageUp)
                flickable.flick(0,  60*Math.sqrt(flickable.height))
              if(event.key === Qt.Key_PageDown)
                flickable.flick(0, -60*Math.sqrt(flickable.height))
            }
          }
          ScrollBar.vertical: ScrollBar { }
        }
      }
    }
    

    But there are two Problems:

    1. It doesn't scroll up if I reach the last visible line and press enter (it does if I remove the line numbers). I guess that's because the ScrollView/ Flickable does only apply to the CodeEditor but not to the lineNumbers?
    2. LineNumbers and Code in the TextArea are not one the same Hight. One Reason for this is that the TextArea has a margin, but even without it they aren't on the same hight (or if I apply a top margin/padding to the lineNumbers).

    I am even not sure if this is the right way to achieve this ... using pane as a root element for example

    It should be one Page of a SwipeView. Is there a better solution?

    By the way, can anyone explain to me what the property clip is? I have some problems understanding what clipping is.

    Greetings Leon



  • This sort-of does what you wanted-

    import QtQuick 2.10
    import QtQuick.Window 2.10
    import QtQuick.Layouts 1.3
    import QtQuick.Controls 2.2
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        Pane {
            anchors.fill: parent
    
            ScrollView {
                anchors.fill: parent
    
                RowLayout {
                    spacing: 0
                    width: parent.parent.width
    
                    ColumnLayout {
                        id: lineNumbers
    
                        Repeater {
                            id: lineNumberRepeater
                            model: editor.lineCount
                            Layout.fillHeight: true
    
                            Text {
                                text: index + 1
                                color: 'lightgray'
                                font.pointSize: editor.font.pointSize
                            }
                        }
                    }
    
                    TextArea {
                        id: editor
                        Layout.fillWidth: true
    
                        focus: true
                        persistentSelection: true
                        selectByMouse: true
                        textMargin: 10
                        wrapMode: Text.WrapAtWordBoundaryOrAnywhere
    
                        Rectangle {
                            anchors.fill: parent
                            color: "red"
                            opacity: 0.1
                        }
                    }
                }
            }
        }
    }
    


  • Doesn't solve things.

    I can scroll now both, but that is not really what I want (at least not completely).

    Actually, I wish, that the scrolling is done automatically. So if I am in the last visible line, the next should be added while the rest is scrolled up by one line.
    In your solution, I have to scroll up manually to see the new lines.

    Furthermore, it would also be awesome to don't miss the feature of flickable. If you have 1000 of lines of code you can go up to line one really fast by pressing and moving up. Kind of throwing the TextArea up/down.



  • @Leon_2001 You realize you can control the region a Flickable is displaying by simply assigning to it's contentY property? (Or binding it to some suitable expression). You're not limited to flickable.flick to move it around from code.



  • @timday I am not quite sure, what you mean by this. I am new to qml, examples help me a lot understanding all these things.

    Anyways, I figured out a working solution. The only thing I maybe could think about, how to use flicking not only in the column but also in the editor itself. At the moment, it isn't possible, because the editor has the focus (which he needs for things like marking text)

    Pane {
      Item {
        id: editorItem
        anchors.fill: parent
    
        Flickable {
          id: flickable
          anchors.fill: parent
          flickableDirection: Flickable.VerticalFlick
          contentWidth: parent.width
          contentHeight: editor.height
    
          ColumnLayout {
            id: lineNumber
            spacing: 0
            Repeater {
              id: lineNumberRepeater
              model: editor.lineCount
              Text {
                text: index + 1
                color: 'lightgray'
                font.pointSize: editor.font.pointSize
              }
            }
          }
          TextArea.flickable: TextArea {
            id: editor
            anchors.left: lineNumber.right
            topPadding: 0
            leftPadding: 20
            rightPadding: 20
            bottomPadding: 0
            background: Rectangle {
               color: "transparent"
               border.color: "transparent"
            }
            font.pointSize: 18
            persistentSelection: true
            selectByMouse: true
            wrapMode: Text.WrapAtWordBoundaryOrAnywhere
    
            Keys.onPressed: {
              if(event.key === Qt.Key_PageUp)
                flickable.flick(0,  60*Math.sqrt(flickable.height))
              if(event.key === Qt.Key_PageDown)
                flickable.flick(0, -60*Math.sqrt(flickable.height))
            }
          }
          ScrollBar.vertical: ScrollBar { }
        }
        Documenthandler {
          id: documenthandler
          document: editor.textDocument
          cursorPosition: editor.cursorPosition
          selectionStart: editor.selectionStart
          selectionEnd: editor.selectionEnd
        }
      }
    }
    

    The solution is simply to put everything in the Flickable and to avoid nesting the TextArea into a RowLayout because TextArea.flickable: TextArea {} won't be working. Instead, I use anchors for the layout.

    Would be interested if there is a solution for the nesting

    Flickable {
      RowLayout {
        ColumnLayout {
        }
        TextArea.flickable: TextArea { //not possible
        }
      }
    }
    

    I have seen in the Documentation that it is sometimes possible to write down, that TextArea is nested -> Something Like TextArea.flickable: RowLayout.TextArea ... don't know


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.