PySide6中QPlainTextEdit移动光标后滚动条长度异常问题
QPlainTextEdit超长行滚动异常问题解决方案
问题描述
Windows 10系统下使用PySide6开发时,QPlainTextEdit组件出现以下异常:
- 设置包含超长行的文本后,将光标定位至第3行,初始显示正常
- 向上滚动时,滚动条长度突然变短,视图直接跳至文本顶部,但光标仍停留在第3行
尝试过的无效方法:
- 仅将垂直滚动条设为0:滚动条长度恢复正常,但视图默认显示文本顶部
- 先记录滚动条位置、滚动至顶部再恢复原位置:无法解决滚动条长度异常问题
复现代码
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 2\n" "Line 3\n" "Line 4\n" "Line 5\n" 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()
解决方案
通过强制触发视图布局计算,并手动定位滚动位置,解决超长行导致的滚动异常:
修改后的代码
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 2\n" "Line 3\n" "Line 4\n" "Line 5\n" 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) # 解决滚动异常的关键代码 self.textEdit.ensureCursorVisible() # 获取目标行的顶部位置并设置滚动条 block_geom = self.textEdit.blockBoundingGeometry(cursor.block()) content_offset = self.textEdit.contentOffset() scroll_top = block_geom.translated(content_offset).top() self.textEdit.verticalScrollBar().setValue(int(scroll_top)) self.setCentralWidget(self.textEdit) app = QApplication(sys.argv) window = MainWindow() window.show() app.exec()
原理说明
ensureCursorVisible()会触发QPlainTextEdit重新计算文本布局,修正超长行导致的滚动条范围计算错误- 手动获取目标行的顶部坐标并设置滚动条位置,确保初始视图准确定位到第3行,同时滚动条的长度和范围恢复正常,后续滚动操作不会再出现跳顶异常
内容的提问来源于stack exchange,提问作者IssaRice
相关产品推荐
相关产品推荐

