Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
QTextEdit extended with a signal 'lineNumbersChanged' which gets triggered when the line-numbers of the visible text change. Such functionality already exists for QPlainTextEdit via firstVisibleBlock().blockNumber() and lastVisibleBlock().blockNumber(). However these methods are not accessible using QTextEdit and PyQt. The signal can be used to …
from PyQt4 import QtGui, QtCore
class TextEdit(QtGui.QTextEdit):
'''
QTextEdit extended with a signal 'lineNumbersChanged' which gets triggered when the line-numbers of the visible text change.
Such functionality already exists for QPlainTextEdit via firstVisibleBlock().blockNumber() and lastVisibleBlock().blockNumber()
However these functions are not accessible using QTextEdit and PyQt.
The signal can be used to update custom widgets that compliment the QTextEdit such as lineNumberWidgets or miniMapWidgets.
'''
lineNumbersChanged = QtCore.pyqtSignal(int, int)
def __init__(self, parent = None):
QtGui.QTextEdit.__init__(self, parent)
self.__reportLineNumberChanges = False # Switch to turn reporting of lineNumbers on/off for performance reasons. E.g. when the miniMap is hidden
self.__firstLineNumber = None # Store the current first line-number
self.__lastLineNumber = None # Store the current last line-number
self.textChanged.connect(self.computeLineNumbersChanged) # Check if the any changes to the text caused the line-numbers to change
def reportLineNumberChanges(self, val):
'''
Turns on/off computation of line-numbers. If it's being turned on, the current line-numbers are being computed.
@param val: Boolean value defining whether to turn computation of line-numbers on/off.
@type val: bool
@rtype: None
'''
self.__reportLineNumberChanges = val
if val:
self.computeLineNumbersChanged()
def firstVisibleBlock(self):
'''
@return: The first visible block of the TextEdit
@rtype: QtGui.QTextBlock
'''
return self.cursorForPosition(QtCore.QPoint(0, 0)).block()
def lastVisibleBlock(self):
'''
@return: The last visible block of the TextEdit
@rtype: QtGui.QTextBlock
'''
return self.cursorForPosition(QtCore.QPoint(0, self.viewport().height() - 1)).block()
def computeLineNumbersChanged(self):
'''
Checks if the current line-numbers have changed since the last time this method was called.
Emits the 'lineNumbersChanged' signal with the line-numbers of the first and last visible block.
@rtype: None
'''
if self.__reportLineNumberChanges: # Check if we actually want to compute line-numbers
firstLineNumber = self.firstVisibleBlock().blockNumber() # Get the line-number of the first visible block.
lastLineNumber = self.lastVisibleBlock().blockNumber() # Get the line-number of the last visible block.
if not firstLineNumber == self.__firstLineNumber or not lastLineNumber == self.__lastLineNumber:
# Line-numbers have changed since the last time they've been computed
self.__firstLineNumber = firstLineNumber # Store the current line-number of the first block
self.__lastLineNumber = lastLineNumber # Store the current line-number of the last block
self.lineNumbersChanged.emit(firstLineNumber, lastLineNumber) # Emit the signal with the line-numbers as values
def wheelEvent(self, event):
''' Override method from parent class. Triggers computation of line-numbers in case mouse-wheel is being used '''
self.computeLineNumbersChanged()
return QtGui.QTextEdit.wheelEvent(self, event)
def resizeEvent(self, event):
''' Override method from parent class. Triggers computation of line-numbers in case widget is being resized '''
self.computeLineNumbersChanged()
return QtGui.QTextEdit.resizeEvent(self, event)
def printNumbers(self, *numbers):
''' Helper method. Only needed to print the computed numbers '''
print numbers
if __name__ == '__main__':
import sys
import urllib2
app = QtGui.QApplication(sys.argv)
te = TextEdit()
te.reportLineNumberChanges(True)
te.lineNumbersChanged.connect(te.printNumbers)
url = 'http://www.manuelmacha.de'
data = urllib2.urlopen(url)
lines= data.readlines()
text = '\n'.join(lines)
te.document().setPlainText(text)
te.show()
te.raise_()
sys.exit(app.exec_())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment