QPlainTextEdit center on custom cursor
-
I use the
QTextEdit::ExtraSelection
capabilities of theQPlainTextEdit
to highlight certain words in the text that is being displayed. Similar to a search function I give the user the ability to jump to the next selection. So far I am able to change the format of the "current selection" and everything works great. The only missing piece is that I scroll theQPlainTextEdit
so that the current selection becomes visible.My idea was to simply create a copy of the currently set text cursor, set the extra selection cursor to be come the new text cursor, calling
QPlainTextEdit::ensureCursorVisible()
and then simply restoring the previous cursor. However, the problem is thatQPlainTextEdit::setTextCursor()
itself already callsQPlainTextEdit::ensureCursorVisible()
. This means that when I reset the cursor back to the previous one the plain text edit simply scrolls back again. Just for completeness, this is the code I was using:const QTextCursor& currentSelectionCursor = extraSelections().at(myFancyCursorIndex).cursor; QTextCursor prevCursor = textCursor(); setTextCursor(currentSelectionCursor); ensureCursorVisible(); setTextCursor(prevCursor);
Can somebody tell me how I can simply scroll my
QPlainTextEdit
so that aQTextCursor
that is NOT the current text cursor is centered?
I know that I can useQPlainTextEdit::cursorRect(const QTextCursor& cursor)
to get the rectangle of the text cursor relative to the viewport but I can't figure out how I can properly calculate the values required forQPlainTextEdit::verticalScrollBar()::setValue()
.
I would prefer that method anyway asensureCursorVisible()
doesn't necessarily center on it.Thanks for the help in advance!
-
I assume there is a prettier solution, but you might be able to tell your vertical scrollbar (QAbstractScrollArea::verticalScrollBar()) to scroll only one full line of text at a time (via QAbstractSlider::setRange(int min, int max)), i.e. set the minimum value to 0 and the maximum to the number of lines of text you have. (That probably needs updating, but that shouldn't be too difficult.)
Then you can callsetValue()
with the line-number of your currently selected text. If you can't get that number, you could make use of thecursorRect()
and the viewports height to calculate it. -
A (dirty but quick) solution could be something like that:
// jump to the desired position ensureCursorVisible(); // remember this position int scrollPos = verticalScrollBar()->value(); // reset the cursor position (and scroll back again) setTextCursor(prevCursor); // scroll again to the remembered position verticalScrollBar()->setValue(scrollPos);
-
@thEClaw said:
If you can't get that number, you could make use of the cursorRect() and the viewports height to calculate it.
My problem is exactly that calculation. I can't figure out the proper way to calculate it. I know that I can query the current height of the viewport but I can't figure out how to get the complete height of the viewport (ie. if there are no scrollbars). I played around with
maximumViewportSize()
but that returned a ridiculously large number (something like 1600000).
What I need to archive is to find a value that lies betweenverticalScrollBar()->minimum()
andverticalScrollBar()->maximum()
.@micland Holy... What a simple solution. No idea why I didn't think of that. Thank you very much! This helps a lot!
-
I played around with scrollbar calculation a long time ago and I remember that it was a bit confusing.
But AFAIR you have to set the QScrollBar::setValue() relative to QScrollBar::maximum() with the same ratio as QAbstractScrollArea::widget()::height() / calculatedPos.
(not sure - just guessing...)