Here is a minimal example to showcase the problem:
import sys
from PySide6.QtGui import QTextCursor
from PySide6.QtWidgets import (
QApplication,
QMainWindow,
QPlainTextEdit,
)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(100, 100, 600, 400)
self.textEdit = QPlainTextEdit(self)
self.textEdit.setPlainText(
f"Line 1 {'aaa ' * 1000}n"
"Line 2n"
"Line 3n"
"Line 4n"
"Line 5n"
f"Line 6 {'aaa ' * 1000}n"
)
cursor = self.textEdit.textCursor()
cursor.movePosition(QTextCursor.Start)
# Move cursor to line 3
cursor.movePosition(QTextCursor.Down, QTextCursor.MoveAnchor, 3 - 1)
self.textEdit.setTextCursor(cursor)
# scrollbarPosition = self.textEdit.verticalScrollBar().value()
# self.textEdit.verticalScrollBar().setValue(0)
# self.textEdit.verticalScrollBar().setValue(scrollbarPosition)
self.setCentralWidget(self.textEdit)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
When I run this on Windows 10, I get:
As you can see, the cursor starts on line 3 as intended. But now if I scroll even a little bit up using my mouse, the following happens:
As you can see, the scrollbar got shorter and the scroll view jumped all the way to the top of the text field. It’s as if Qt didn’t know that lines 1 and 2 were there (or more precisely, it knew the lines were there but didn’t expect line 1 to be so long), and when I scrolled up it figured out that there was text above line 3, and then loaded them up, and then jumped all the way to the top. The cursor remains on line 3, however (which is good).
If I uncomment just the line
self.textEdit.verticalScrollBar().setValue(0)
from above, then the scrollbar’s length is correct, but of course the scroll view starts at the top rather than on line 3.
If I uncomment all three of:
scrollbarPosition = self.textEdit.verticalScrollBar().value()
self.textEdit.verticalScrollBar().setValue(0)
self.textEdit.verticalScrollBar().setValue(scrollbarPosition)
to try to remember the initial scrollbar position, go to the top (hopefully to load the content at the top), then scroll back down to line 3, then the result is exactly the same as in the initial program — the scrollbar’s length is now incorrect!
How can I get it so that the scrollbar’s length doesn’t change when scrolling, and the program starts on line 3, and if I scroll up a bit, it just shows line 2 and the last bit of line 1 (rather than jumping all the way to the beginning of the text field)?