Fra*_*une 6 c++ qt scroll qtextedit qtextcursor
我对此进行了广泛的研究,但还没有找到令人满意的解决方案:
当满足以下任一条件时,如何在 QTextEdit 小部件的末尾附加文本而不触发到小部件底部的滚动:
(在所有其他情况下,应该触发滚动到 QTextEdit 小部件的底部。)
这是我目前用来附加text在 QTextEdit 底部的代码widget:
const QTextCursor old_cursor = widget.textCursor();
widget.moveCursor(QTextCursor::End);
widget.textCursor().insertText(text);
if (old_cursor.hasSelection())
widget.setTextCursor(old_cursor);
else widget.moveCursor(QTextCursor::End);
Run Code Online (Sandbox Code Playgroud)
这部分解决了条件 1:问题是视图仍然会滚动,直到只有选择的最后一行可见,此时它确实会停止滚动。
条件 2 根本没有得到处理:一些帖子建议保存垂直滚动条的位置并在附加文本后恢复它,但是我认为这是不正确的,因为在附加文本时滚动条应该向上移动,即使视图保持静止。
请注意,我使用的是QTextCursor::insertText()而不是QTextEdit::append()因为我需要调整附加文本的颜色,无论用户是否选择了文本。
更新:这是我最终得到的代码,感谢 Pavel 的回答:
const QTextCursor old_cursor = widget.textCursor();
const int old_scrollbar_value = widget.verticalScrollBar()->value();
const bool is_scrolled_down = old_scrollbar_value == widget.verticalScrollBar()->maximum();
// Move the cursor to the end of the document.
widget.moveCursor(QTextCursor::End);
// Insert the text at the position of the cursor (which is the end of the document).
widget.textCursor().insertText(text);
if (old_cursor.hasSelection() || !is_scrolled_down)
{
// The user has selected text or scrolled away from the bottom: maintain position.
widget.setTextCursor(old_cursor);
widget.verticalScrollBar()->setValue(old_scrollbar_value);
}
else
{
// The user hasn't selected any text and the scrollbar is at the bottom: scroll to the bottom.
widget.moveCursor(QTextCursor::End);
widget.verticalScrollBar()->setValue(verticalScrollBar()->maximum());
}
Run Code Online (Sandbox Code Playgroud)
保存和恢复滚动条位置是非常正确的并且完美运行。当文档长度增加时,滚动条的最大值增加。但它的值仍然等于视口上方的像素数。因此,当您向文档添加内容并重复设置相同的滚动条值时,滚动条的手柄将移动到顶部,但内容将保持不动。
您似乎已经知道如何检查用户是否选择了某些文本。要检查用户是否已从底部滚动,您应该简单地将垂直滚动条的值与其最大值进行比较。