Important: Please read the Qt Code of Conduct -

Unable to interact with TextEdit content inside Flickable that is not exposed when Flickable is in its default position

  • Hi,

    I am currently trying to develop a basic code editor in QML. I want to have a TextEdit inside of a Flickable, and have begun to write some code to update the Flickable view based on the cursor position (this nearly works perfectly).

    However, I am unable to select text with the mouse in the TextEdit where it was not available when the Flickable's contentY is set to 0. On my monitor this is 42 lines, so it is not possible to interact with line 43 onwards. If I have selected text from before line 43, I can select text beyond line 43 but I cannot start beyond this point. Obviously, for a code editor, not being able to position the cursor or select text for anything beyond the first few lines is hugely impractical.

    I have included the code snippet below - any advice would be appreciated.

    ScrollView {
        id: root
        anchors.right: parent.right
        height: parent.height
        width: parent.width
        frameVisible: false
        Flickable {
            id: flick
            boundsBehavior: Flickable.StopAtBounds
            width: parent.width;
            height: parent.height;
            contentWidth: codeInputText.paintedWidth
            contentHeight: codeInputText.paintedHeight
            clip: true
            onContentYChanged: {
                codeInputText.firstVisibleLineNum = (contentY/codeInputText.lineHeight) + 1
                var lastVisibleScrollableLineNum = codeInputText.maxVisibleLines + codeInputText.firstVisibleLineNum - 1
                codeInputText.lastVisibleLineNum = Math.min(Math.floor(lastVisibleScrollableLineNum), codeInputText.lineCount)
            TextEdit {
                property var fontSize: 20
                property var firstVisibleLineNum: 1
                property var lastVisibleLineNum: lineCount
                property var lineHeight: paintedHeight/lineCount
                property var maxVisibleLines: height/lineHeight
                focus: true
                id: codeInputText
                objectName: "codeInputText"
                wrapMode: TextEdit.WrapAnywhere
                baseUrl: "qrc:/"
                text: ""
                textFormat: Qt.PlainText
                color: "white"
       "Courier New"
                font.pixelSize: fontSize
                width: flick.width
                height: flick.height
                onCursorPositionChanged: {
                    // If cursor position is out of line of sight, update view
                    var lines = text.split("\n");
                    var charsSoFar = 0;
                    var cursorLine = 1;
                    for (var i = 0; i < lines.length; i++) {
                        var line = lines[i];
                        var newCharsSoFar = charsSoFar + line.length + i
                        if (newCharsSoFar >= cursorPosition) {
                            cursorLine = i + 1;
                        } else  {
                            charsSoFar = charsSoFar + line.length;
                    // Update view to show current line number
                    if (cursorLine < firstVisibleLineNum) {
                        // Move up - make first visible line == cursor line
                        flick.contentY = (cursorLine - 1) * lineHeight
                    } else if (cursorLine > lastVisibleLineNum) {
                        // Move down - make last visible line == cursor line
                        flick.contentY = ((cursorLine) * lineHeight) - height