QPlainTextEdit center on custom cursor
I use the
QTextEdit::ExtraSelectioncapabilities of the
QPlainTextEditto 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 the
QPlainTextEditso 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 that
QPlainTextEdit::setTextCursor()itself already calls
QPlainTextEdit::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
QPlainTextEditso that a
QTextCursorthat is NOT the current text cursor is centered?
I know that I can use
QPlainTextEdit::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 for
I would prefer that method anyway as
ensureCursorVisible()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 call
setValue()with the line-number of your currently selected text. If you can't get that number, you could make use of the
cursorRect()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);
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 between
@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...)