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:
- 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?
- 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 toflickable.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