2014-02-22 27 views
4

我已經廣泛地研究這一點,但還沒有找到一個滿意的解決方案還滾動的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()); 
} 
+3

保存和恢復滾動條的位置是非常正確的,完美的作品。當文檔長度增加時,滾動條的最大值增加。但是它的值仍然等於視口上方的像素數量。因此,當您向文檔添加內容並重復設置相同的滾動條值時,滾動條的手柄將移動到頂部,但內容將保持不動。看來你已經知道如何檢查用戶是否選擇了一些文本。要檢查用戶是否從底部滾動,應該簡單地比較垂直滾動條的值和最大值。 –

+0

非常感謝Pavel,你絕對正確。作出正式答案,我會接受它(併發布我的解決方案,以供將來參考)。 –

回答

4

保存和恢復滾動條的立場是非常正確和完美的作品。當文檔長度增加時,滾動條的最大值增加。但是它的值仍然等於視口上方的像素數量。因此,當您向文檔添加內容並重復設置相同的滾動條值時,滾動條的手柄將移動到頂部,但內容將保持不動。

看來你已經知道如何檢查用戶是否選擇了一些文本。要檢查用戶是否從底部滾動,應該簡單地比較垂直滾動條的值和最大值。