Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct
QPlainTextEdit center on custom cursor
Joel Bodenmann last edited by Joel Bodenmann
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!
thEClaw last edited by
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.
micland last edited by
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);
Joel Bodenmann last edited by
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!
micland last edited by
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...)