Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt for Python
  4. Get XY Coordinates of QTextCursor
Forum Updated to NodeBB v4.3 + New Features

Get XY Coordinates of QTextCursor

Scheduled Pinned Locked Moved Solved Qt for Python
3 Posts 2 Posters 160 Views 1 Watching
  • 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.
  • D Offline
    D Offline
    DonJS
    wrote 28 days ago last edited by
    #1

    I am using PySide6 and wondering how I can get a QRect or a QPoint of the QTextCursor's position in a QTextDocument. My QTextDocument is painted on a QWidget using the QAbstractTextDocumentLayout.draw() function. Using a QTextEdit you can get the QRect of the QTextCursor by using the QTextEdit.cursorRect() function. My need for this is that when you enter text into my simple word processing app (see screenshot), you have to manually scroll the QScrollArea to keep the text cursor in view. I want to use the QScrollArea.ensureVisible() function to keep the text cursor in the viewport, but I seemingly have no way of getting any X/Y coordinates of the QTextCursor. I have experimented using the blockBoundingRect and frameBoundingRect and while the blockBoundingRect gets close, it is still too large an area for that to work. I've exhausted my ideas and I hope someone has a suggestion for me. Maybe someone understands the source code of QTextEdit.cursorRect well enough to help me create an equivalent in PySide6.

    screencapture.jpg

    1 Reply Last reply
    0
    • I Offline
      I Offline
      IgKh
      wrote 28 days ago last edited by
      #2

      Hi @DonJS and welcome.

      Assuming you are using the standard Qt implementation of QAbstractTextDocumentLayout and not implementing your own, it is very roughly something like this:

      1. Get the QTextBlock for the cursor, and take the block's QTextLayout via the layout method.
      2. Get the specific actual QTextLine that has that position by calling the layout's lineForTextPosition with the cursor's position relative to its' block start.
      3. If result is valid, use cursorToX to get the x-position relative to the line.
      4. Consider the line and block layout positions to get the (x,y) coordinates relative to document.
      5. Convert from document coordinates to viewport coordinates based on whatever margin or such you are using.

      Probably needs a bit of trial and error to get exactly right.

      D 1 Reply Last reply 27 days ago
      2
      • I IgKh
        28 days ago

        Hi @DonJS and welcome.

        Assuming you are using the standard Qt implementation of QAbstractTextDocumentLayout and not implementing your own, it is very roughly something like this:

        1. Get the QTextBlock for the cursor, and take the block's QTextLayout via the layout method.
        2. Get the specific actual QTextLine that has that position by calling the layout's lineForTextPosition with the cursor's position relative to its' block start.
        3. If result is valid, use cursorToX to get the x-position relative to the line.
        4. Consider the line and block layout positions to get the (x,y) coordinates relative to document.
        5. Convert from document coordinates to viewport coordinates based on whatever margin or such you are using.

        Probably needs a bit of trial and error to get exactly right.

        D Offline
        D Offline
        DonJS
        wrote 27 days ago last edited by
        #3

        @IgKh
        Thanks so much for your direction. That was exactly what I needed! Here is the code I used:

        #####determine the cursor position to scroll the scrollArea as needed
                
                #get the blockBoundingRect of the block that holds the QTextCursor
                blockRect = self.doc.documentLayout().blockBoundingRect(self.cur.block())
                #get the QTextLine that holds the QTextCursor
                cursorLine = self.cur.block().layout().lineForTextPosition(self.cur.positionInBlock())
                #get the QTextLine's naturalTextRect so we can get the Y center of the QTextCursor
                self.cursorLineRect = cursorLine.naturalTextRect()
                #translate the cursorLineRect to the blockRect
                self.cursorLineRect.translate(blockRect.x(),blockRect.y())
                #get the approximate X position of the cursor
                cursorToX = cursorLine.cursorToX(self.cur.positionInBlock(), QTextLine.Edge.Leading)
                #create a QPointF from the cursorToX posistion and the center of the CursorLineRect
                self.cursorPoint=QPointF(float(cursorToX[0])+blockRect.x(),self.cursorLineRect.center().y())
                #instruct the QScrollArea to keep the QPointF visible with 100px padding
                self.main_window.scrollArea.ensureVisible(self.cursorPoint.x(), self.cursorPoint.y(),100,100)
        

        Then to confirm my computation was correct I painted self.cursorPoint using painter.drawPoint(self.cursorPoint) . You can see the little red dot following the text cursor in the screenshot below. Your guidance solved my problem 100%

        cursor_stays_in_viewport.JPG

        1 Reply Last reply
        1
        • D DonJS has marked this topic as solved 27 days ago

        1/3

        6 May 2025, 17:36

        • Login

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