Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. QML TextEdit get current cursor position
Forum Updated to NodeBB v4.3 + New Features

QML TextEdit get current cursor position

Scheduled Pinned Locked Moved Solved QML and Qt Quick
4 Posts 2 Posters 514 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Anonimista
    wrote on 4 Sept 2024, 11:56 last edited by
    #1

    I am trying to get cursor row and column in the TextEdit control so I can put that information in the status bar (footer). I am trying to use QTextCursor as I would in Qt Widgets but in my Python slot (CharCounter.cursor.position) I always get 0, 0, as the position

    view.qml

    import QtQuick
    import QtQuick.Controls
    import QtQuick.Layouts
    
    import examples.charcounter
    
    
    ApplicationWindow {
    
        visible: true
        width: 400
        height:200
        title: "Template App"
        
        CharCounter {
            id: charCounter
        }
    
        RowLayout {
            
            anchors.fill: parent
                
            TextArea {
            
                id: textArea
            
                text: "Hello Qml!"
    
                Layout.fillWidth: true
                Layout.fillHeight: true
                
                onTextChanged: {
                    charCounter.cursor_position(textDocument)
                }
            }
        }
        
        footer: RowLayout {
            Label {
                id: statusLabel
            }
        }
    }
    

    main.py

    import sys
    
    from PySide6.QtGui import QGuiApplication, QTextDocument, QTextCursor
    from PySide6.QtQml import QQmlApplicationEngine, QmlElement
    from PySide6.QtCore import QObject, Slot
    from PySide6.QtQuick import QQuickTextDocument
    
    
    QML_IMPORT_NAME = 'examples.charcounter'
    QML_IMPORT_MAJOR_VERSION = 1
    
    @QmlElement
    class CharCounter(QObject):
        
        def __init__(self, parent=None):
            super().__init__(parent)
            
        @Slot(QQuickTextDocument)
        def cursor_position(self, textDocument):
            #print(textDocument.textDocument().toPlainText())
            cursor = QTextCursor(textDocument.textDocument())
            print(cursor.blockNumber(), cursor.columnNumber())
    
    
    if __name__ == '__main__':
    
        app = QGuiApplication(sys.argv)
        
        engine = QQmlApplicationEngine()
        engine.quit.connect(app.quit)
        engine.load('view.qml')
    
        result = app.exec()
        del engine
        
        sys.exit(result)
    
    1 Reply Last reply
    0
    • B Offline
      B Offline
      Bob64
      wrote on 4 Sept 2024, 14:17 last edited by
      #2

      I see what you are trying to do but I think the issue is that you are creating a new cursor that, according to the documentation, will initialise itself at position (0, 0) of the document. There is no intrinsic cursor position stored in the document itself that the new cursor will acquire.

      Meanwhile, presumably the internals of the QML code has its own cursor object that knows where it is within the document.

      As for what you want to achieve, I'm afraid I don't see an obvious way to do it. But I am not an expert and maybe someone else will be able to suggest something.

      A 1 Reply Last reply 4 Sept 2024, 15:50
      2
      • B Bob64
        4 Sept 2024, 14:17

        I see what you are trying to do but I think the issue is that you are creating a new cursor that, according to the documentation, will initialise itself at position (0, 0) of the document. There is no intrinsic cursor position stored in the document itself that the new cursor will acquire.

        Meanwhile, presumably the internals of the QML code has its own cursor object that knows where it is within the document.

        As for what you want to achieve, I'm afraid I don't see an obvious way to do it. But I am not an expert and maybe someone else will be able to suggest something.

        A Offline
        A Offline
        Anonimista
        wrote on 4 Sept 2024, 15:50 last edited by
        #3

        @Bob64 Hey thanks! I actually got it to work using TextArea.cursorPosition. Turns out QTextCursor has a setPosition() method so I just set the cursor position immediately after creating it. On the Qml side I had to use onCursorPositionChanged instead of onTextChanged so the label is updated on cursor movement. Here is the full code for reference

        main.py

        import sys
        
        from PySide6.QtGui import QGuiApplication, QTextCursor
        from PySide6.QtQml import QQmlApplicationEngine, QmlElement
        from PySide6.QtCore import QObject, Slot
        from PySide6.QtQuick import QQuickTextDocument
        
        
        QML_IMPORT_NAME = 'examples.charcounter'
        QML_IMPORT_MAJOR_VERSION = 1
        
        @QmlElement
        class CharCounter(QObject):
            
            def __init__(self, parent=None):
                super().__init__(parent)
                
            @Slot(QQuickTextDocument, int, result=list)
            def cursor_position(self, textDocument, cursorPosition):
        
                cursor = QTextCursor(textDocument.textDocument())
                cursor.setPosition(cursorPosition)
                return (cursor.blockNumber(), cursor.columnNumber())
        
        
        if __name__ == '__main__':
        
            app = QGuiApplication(sys.argv)
            
            engine = QQmlApplicationEngine()
            engine.quit.connect(app.quit)
            engine.load('view.qml')
        
            result = app.exec()
            del engine
            
            sys.exit(result)
        

        view.qml

        import QtQuick
        import QtQuick.Controls
        import QtQuick.Layouts
        
        import examples.charcounter
        
        
        ApplicationWindow {
        
            visible: true
            width: 400
            height:200
            title: "Template App"
            
            CharCounter {
                id: charCounter
            }
        
            RowLayout {
                
                anchors.fill: parent
                    
                TextArea {
                
                    id: textArea
                
                    text: "Hello Qml!"
        
                    Layout.fillWidth: true
                    Layout.fillHeight: true
                    
                    onCursorPositionChanged: {
                        let [row, col] =  charCounter.cursor_position(
                            textDocument, cursorPosition)
                        statusLabel.text = "row: " + row + 
                            ", col: " + col
                    }
                }
            }
            
            footer: RowLayout {
                Label {
                    id: statusLabel
                }
            }
        }
        
        1 Reply Last reply
        1
        • A Anonimista has marked this topic as solved on 5 Sept 2024, 05:38
        • B Offline
          B Offline
          Bob64
          wrote on 5 Sept 2024, 08:26 last edited by
          #4

          I had seen the cursorPosition property but I couldn't see a way to translate that into a row and column position in the document. Your solution seems to do that. Nice!

          1 Reply Last reply
          0

          1/4

          4 Sept 2024, 11:56

          • Login

          • Login or register to search.
          1 out of 4
          • First post
            1/4
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved