How to get/set the position of the scroll area?

Heads up! You've already completed this tutorial.

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: .

PyQt/PySide 1:1 Coaching with Martin Fitzpatrick — Get one on one help with your Python GUI projects. Working together with you I'll identify issues and suggest fixes, from bugs and usability to architecture and maintainability.

Book Now 60 mins ($195)

python
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

Over 10,000 developers have bought Create GUI Applications with Python & Qt!
Create GUI Applications with Python & Qt6
Take a look

Downloadable ebook (PDF, ePub) & Complete Source code

Also available from Leanpub and Amazon Paperback

[[ discount.discount_pc ]]% OFF for the next [[ discount.duration ]] [[discount.description ]] with the code [[ discount.coupon_code ]]

Purchasing Power Parity

Developers in [[ country ]] get [[ discount.discount_pc ]]% OFF on all books & courses with code [[ discount.coupon_code ]]

Thank you! This worked out just fine. I used the preserve_viewport() and it's exactly what I needed.


Create GUI Applications with Python & Qt5 by Martin Fitzpatrick — (PyQt5 Edition) The hands-on guide to making apps with Python — Over 10,000 copies sold!

More info Get the book

Well done, you've finished this tutorial! Mark As Complete
[[ user.completed.length ]] completed [[ user.streak+1 ]] day streak
Martin Fitzpatrick

How to get/set the position of the scroll area? was written by Martin Fitzpatrick .

Martin Fitzpatrick has been developing Python/Qt apps for 8 years. Building desktop applications to make data-analysis tools more user-friendly, Python was the obvious choice. Starting with Tk, later moving to wxWidgets and finally adopting PyQt. Martin founded PythonGUIs to provide easy to follow GUI programming tutorials to the Python community. He has written a number of popular https://www.martinfitzpatrick.com/browse/books/ on the subject.