我已經廣泛地研究這一點,但還沒有找到一個滿意的解決方案還滾動的QTextEdit控件:防止當有一個選擇
如何追加在的QTextEdit控件結束文本,而不會觸發滾動到當滿足以下任一條件時,該部件的底部:
- 用戶選擇了一些文本。
- 用戶已從底部滾動。
(在其他情況下,滾動到的QTextEdit控件的底部應該被觸發。)
這是我目前使用在一個QTextEdit widget
的底部追加text
的代碼:
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);
這部分需要照顧的條件1:問題是,認爲仍然會滾動,直至僅選擇的最後一行是可見的,此時它的確將停止滾動。
條件2根本不在意:有些帖子建議保存垂直滾動條的位置並在文本被追加後恢復它,但是我不認爲這是正確的,因爲滾動條應該向上移動文本被追加,即使視圖保持不變。
請注意,我使用的是QTextCursor::insertText()
而不是QTextEdit::append()
,因爲無論用戶是否選擇了文本,我都需要調整所附文本的顏色。
更新:這裏是我最終的代碼,這要歸功於帕維爾的回答是:
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());
}
保存和恢復滾動條的位置是非常正確的,完美的作品。當文檔長度增加時,滾動條的最大值增加。但是它的值仍然等於視口上方的像素數量。因此,當您向文檔添加內容並重復設置相同的滾動條值時,滾動條的手柄將移動到頂部,但內容將保持不動。看來你已經知道如何檢查用戶是否選擇了一些文本。要檢查用戶是否從底部滾動,應該簡單地比較垂直滾動條的值和最大值。 –
非常感謝Pavel,你絕對正確。作出正式答案,我會接受它(併發布我的解決方案,以供將來參考)。 –