Reputation: 439
I have a popup that only contains a QTextEdit, it has a lot of text in it, a lot of lines. I want it to scroll to a certain line in the QTextEdit on show(). So that the line I want is at the top.
Code snippet:
editor = QtGui.QTextEdit()
# fill the editor with text
# set the scroll to nth line
editor.show()
How can I achieve that?
I've managed to get it to show the nth line at the bottom:
cursor = QtGui.QTextCursor(editor.document().findBlockByLineNumber(n))
editor.moveCursor(QtGui.QTextCursor.End)
editor.setTextCursor(cursor)
For example for n=25 I get:
_______________________
.
.
.
.
25th line
_______________________
But I need it to be at the top...
Upvotes: 4
Views: 2952
Reputation: 120608
You almost have it. The trick is to move the current cursor to the bottom first, and then reset the cursor to the target line. The view will then automatically scroll to make the cursor visible:
editor.moveCursor(QtGui.QTextCursor.End)
cursor = QtGui.QTextCursor(editor.document().findBlockByLineNumber(n))
editor.setTextCursor(cursor)
By extension, to position the cursor at the bottom, move the current cursor to the start first:
editor.moveCursor(QtGui.QTextCursor.Start)
...
Here's a demo script:
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.edit = QtGui.QTextEdit(self)
self.edit.setPlainText(
'\n'.join('%04d - blah blah blah' % i for i in range(200)))
self.button = QtGui.QPushButton('Go To Line', self)
self.button.clicked.connect(self.handleButton)
self.spin = QtGui.QSpinBox(self)
self.spin.setRange(0, 199)
self.spin.setValue(50)
self.check = QtGui.QCheckBox('Scroll Top')
self.check.setChecked(True)
layout = QtGui.QGridLayout(self)
layout.addWidget(self.edit, 0, 0, 1, 3)
layout.addWidget(self.button, 1, 0)
layout.addWidget(self.spin, 1, 1)
layout.addWidget(self.check, 1, 2)
QtCore.QTimer.singleShot(0, lambda: self.scrollToLine(50))
def scrollToLine(self, line=0):
if self.check.isChecked():
self.edit.moveCursor(QtGui.QTextCursor.End)
else:
self.edit.moveCursor(QtGui.QTextCursor.Start)
cursor = QtGui.QTextCursor(
self.edit.document().findBlockByLineNumber(line))
self.edit.setTextCursor(cursor)
def handleButton(self):
self.scrollToLine(self.spin.value())
self.edit.setFocus()
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 100, 400, 300)
window.show()
sys.exit(app.exec_())
Upvotes: 4