Reputation: 325
There's a QTextEdit that displays quite a lot of text. It is NOT editable. Suppose I want to read something around the beginning, scroll up, but then a new line is added and the scrollbar automatically goes to the bottom. I experience similar problems when using various programs (regardless of the language they were written in). How does one deal with this problem?
The behavior I want when a new line is added to the text:
I suppose that ensureCursorVisible() is not the solution, since the QTextEdit is not editable, the user won't click inside it, and the position of the cursor is not the same as the position of the vertical scrollbar.
Upvotes: 4
Views: 14014
Reputation: 121
It is not necessary to connect a scrollbar listener. Just query the scrollbar before appending text:
QScrollBar *scrollbar = textedit->verticalScrollBar();
bool scrollbarAtBottom = (scrollbar->value() >= (scrollbar->maximum() - 4));
int scrollbarPrevValue = scrollbar->value();
The "minus 4" hack in scrollbarAtBottom
is necessary since ensureCursorVisible()
does not scroll exactly to the bottom, but some fixed amount above. Check it with your font sizes.
Now you can insert the text:
textedit->moveCursor(QTextCursor::End);
// begin with newline if text is not empty
if (! textedit->document()->isEmpty())
textedit->insertHtml(QStringLiteral("<br>"));
textedit->insertHtml(QStringLiteral("My text here."))
After that operation, either scroll to the bottom, or fix the scrollbar such that it does not move at all:
if (scrollbarAtBottom)
textedit->ensureCursorVisible();
else
textedit->verticalScrollBar()->setValue(scrollbarPrevValue);
Upvotes: 5
Reputation: 32393
I would make Scroll bar position listener, which will remember position on scrolling (and also check is it at the bottom or not).
Then, when new line is added, check is it at bottom, if is scroll down, if is somewhere else then scroll back to that position.
Check this QScrollBar, you can grab it from QTextEdit via horizontalScrollBar() and verticalScrollBar().
More concrete, I would connect slot with signal from QScrollBar - valueChanged(int value) and play with values as it is described here.
Upvotes: 3