ERIC_HUYGEN | 2021-02-02 18:12:09 UTC | #1
Hi,
I have a QTextEdit widget in a QScrollArea. The text is updated frequently and every time this happens, the scroll is set back to the beginning of the text. I update the text with setText() on the QEditText. Is there a way to retrieve and set back the position in the scroll area such that after the updated text, the position is the same as before? Or is that not the way to keep the scroll position?
Thanks, Rik
Salem_Bream | 2021-02-09 13:04:33 UTC | #2
Hi, I am not aware if such thing available in the Qt.
Here, I made custom implementation (3 ways), I used the third one in the demo, feel free to test them and use whichever one you like :smiley: .
Packaging Python Applications with PyInstaller by Martin Fitzpatrick — This step-by-step guide walks you through packaging your own Python applications from simple examples to complete installers and signed executables.
from PyQt5.QtGui import QTextCursor
from PyQt5.QtWidgets import QPushButton, QTextEdit, QApplication
import random
app = QApplication([])
t = QTextEdit()
b = QPushButton("Click!!")
def preserve_cursor():
c = t.textCursor()
p = c.position()
a = c.anchor()
t.setText(
" ".join("".join(chr(random.randint(ord('a'), ord('z')))
for _ in range(6)) for __ in range(1555))
)
c.setPosition(a)
op = QTextCursor.NextCharacter if p > a else QTextCursor.PreviousCharacter
c.movePosition(op, QTextCursor.KeepAnchor, abs(p - a))
t.setTextCursor(c)
def preserve_viewport():
vsb = t.verticalScrollBar()
old_pos_ratio = vsb.value() / (vsb.maximum() or 1)
t.setText(
" ".join("".join(chr(random.randint(ord('a'), ord('z')))
for _ in range(6)) for __ in range(1555))
)
vsb.setValue(round(old_pos_ratio * vsb.maximum()))
def full_preserve():
c = t.textCursor()
p = c.position()
a = c.anchor()
vsb = t.verticalScrollBar()
old_pos_ratio = vsb.value() / (vsb.maximum() or 1)
t.setText(
" ".join("".join(chr(random.randint(ord('a'), ord('z')))
for _ in range(6)) for __ in range(1555))
)
c.setPosition(a)
op = QTextCursor.NextCharacter if p > a else QTextCursor.PreviousCharacter
c.movePosition(op, QTextCursor.KeepAnchor, abs(p - a))
t.setTextCursor(c)
vsb.setValue(round(old_pos_ratio * vsb.maximum()))
b.clicked.connect(
full_preserve
)
t.show()
b.show()
app.exec_()
ERIC_HUYGEN | 2021-02-09 13:05:07 UTC | #3
@Salem_Bream
Thank you! This worked out just fine. I used the preserve_viewport()
and it's exactly what I needed.