I'm trying to get the bounding box of a series of text selections stored in a list. The bounding box is the smallest rectangle that can contain the whole selection. Each item in the list has a start and end point measured in characters from the beginning of the QTextEdit
window and also a letter identifier. QTextEdit.cursorRect(cursor)
should do this, but is producing nonsensical box dimensions:
id: A -- PySide.QtCore.QRect(0, 0, 1, 10)
id: B -- PySide.QtCore.QRect(0, 0, 1, 10)
id: C -- PySide.QtCore.QRect(0, 0, 1, 10)
The selections all start at different points so (0,0) is not correct in viewpoint coordinates. Also, some of them span several lines so the width and height should vary. The problem may be that the cursor is in a loop and I don't set it with setTextCursor
until after the loop finishes. I do this because I'm also rendering the selections as highlights. How can I get cursorRect
to work correctly or otherwise get a separate bounding box for each selection? Here is the code:
import sys
from PySide.QtCore import *
from PySide.QtGui import *
db = ((5,8,'A'),(20,35,'B'),(45,60,'C')) # start, end, and identifier of highlights
class TextEditor(QTextEdit):
def __init__(self, parent=None):
super().__init__(parent)
text="This is example text that is several lines\nlong and also\nstrangely broken up and can be\nwrapped."
self.setText(text)
for n in range(0,len(db)):
row = db[n]
startChar = row[0]
endChar = row[1]
id = row[2]
cursor = self.textCursor()
cursor.setPosition(startChar)
cursor.movePosition(QTextCursor.NextCharacter, QTextCursor.KeepAnchor, endChar-startChar)
rect = self.cursorRect(cursor)
print("id: %s -- %s" % (id,str(rect)))
charfmt = cursor.charFormat()
charfmt.setBackground(QColor(Qt.yellow))
cursor.setCharFormat(charfmt)
cursor.clearSelection()
self.setTextCursor(cursor)
if __name__ == '__main__':
app = QApplication(sys.argv)
editor = TextEditor()
editor.show()
app.exec_()
sys.exit(app.exec_())
EDIT 1:
Here is the text from the program. I'll use CAPS for the highlighted text:
This IS example text THAT IS SEVERAL lines
loNG AND ALSO
STRangely broken up and can be
wrapped.
Let's assume every character is 10 pixels by 10 pixels. The "IS " starts 5 characters in and extends for 3 characters (including a space at the end). So, the upper left corner of the "I" would be at x=50,y=0. The bottom right corner of the space would be at x=80,y=10. If the bounding rectangle is given in coordinates, it would be (50,0,80,10). If the bounding rectangle is given in starting coordinates and size, it would be (50,0,30,10).
On the second line is a highlight that continues to the third line. Its leftmost character is the "S" at the start of line 3, which is at x=0. Its rightmost character is the "O" in "ALSO" which ends at x=130. Its topmost line is the second line, which begins at y=10. Its bottom most line is the third line, which ends at y=30. So, the bounding box would be (0,10,130,30) in coordinates or (0,10,130,20) in starting point and size.