QSyntaxHighlighter: highlighBlock() isn't called again upon text change (PyQt)
-
Hi,
I wrote a simple QSyntaxHighlighter subclass in PyQt. In my main window code I installed an instance of it on plainTextEdit.document(). When I start my application, the keywords are highlighted as expected, but whenever I make any change in the QPlainTextEdit instance, the whole line loses syntax highlight and highlightBlock() isn't called again. Any ideas?
I'm using PyQt from "PyQt4-4.10-gpl-Py3.3-Qt5.0.1-x32-2.exe" with Python 3.3.
test.py:
@# -- coding: utf-8 --import sys, codecs, highlighter
from PyQt4.QtGui import *
from PyQt4.QtCore import *class Example(QMainWindow):
def init(self):
super(Example, self).init()self.initUI()
def initUI(self):
exitAction = QAction("&Exit", self)
exitAction.setShortcut("Ctrl+Q")
exitAction.triggered.connect(qApp.quit)openFileAction = QAction(QIcon("file_open.png"), "&Open", self)
openFileAction.setShortcut("Ctrl+O")Menubar
menuBar = self.menuBar()
fileMenu = menuBar.addMenu("&File")
fileMenu.addAction(openFileAction)
fileMenu.addAction(exitAction)Toolbar
self.toolbar = self.addToolBar("File")
#self.toolbar.setSize(100, 200);
self.toolbar.addAction(openFileAction)
configCB = QComboBox(self.toolbar)
configCB.addItems(["Jedna", "Dva"])
self.toolbar.addWidget(configCB)self.messageShown = True
timer = QTimer(self)
timer.timeout.connect(self.addText)
timer.start(500)model = QFileSystemModel(self)
model.setRootPath("C:/Users/are.bkr-cr/Documents/")
tree = QTreeView(self)
tree.setModel(model)buildLogText = QPlainTextEdit()
buildLogText.setPlainText(u"Výpis kompilace")codeTextEdit = QPlainTextEdit()
codeTextEdit.setFont(QFont("Courier", 11))
myHighlighter = highlighter.Highlighter(codeTextEdit.document())
codeTextEdit.setPlainText(codecs.open("application.c", "r", "utf-8").read())hsplitter = QSplitter(Qt.Horizontal, self)
hsplitter.addWidget(tree)
hsplitter.addWidget(codeTextEdit)vsplitter = QSplitter(Qt.Vertical, self)
vsplitter.addWidget(hsplitter)
vsplitter.addWidget(buildLogText)self.setGeometry(100, 100, 900, 900)
self.setWindowTitle("Coverage tool")
self.setCentralWidget(vsplitter)
self.show()
hsplitter.moveSplitter(hsplitter.width() * 0.25, 1)
vsplitter.moveSplitter(vsplitter.height() * 0.75, 1)def addText(self):
if self.messageShown:
self.statusBar().showMessage("Ready")
else:
self.statusBar().clearMessage()
self.messageShown = not self.messageShowndef main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())if name == 'main':
main()@highlighter.py:
@# -- coding: utf-8 --from PyQt4.QtGui import *
from PyQt4.QtCore import *class HighlightingRule:
passclass Highlighter(QSyntaxHighlighter):
def init(self, parent = None):
super(Highlighter, self).init(parent)self.keywordFormat = QTextCharFormat()
self.keywordFormat.setForeground(Qt.darkBlue)
self.keywordFormat.setFontWeight(QFont.Bold)
keywordPatterns = ["\bchar\b", "\bclass\b", "\bconst\b",
"\bdouble\b", "\benum\b", "\bexplicit\b",
"\bfriend\b", "\binline\b", "\bint\b",
"\blong\b", "\bnamespace\b", "\boperator\b",
"\bprivate\b", "\bprotected\b", "\bpublic\b",
"\bshort\b", "\bsignals\b", "\bsigned\b",
"\bslots\b", "\bstatic\b", "\bstruct\b",
"\btemplate\b", "\btypedef\b", "\btypename\b",
"\bunion\b", "\bunsigned\b", "\bvirtual\b",
"\bvoid\b", "\bvolatile\b"]self.highlightingRules = []
for pattern in keywordPatterns:
rule = HighlightingRule()
rule.pattern = QRegExp(pattern)
rule.format = self.keywordFormat
self.highlightingRules.append(rule)def highlightBlock(self, text):
print("HB called " + text[0:10])
for rule in self.highlightingRules:
index = rule.pattern.indexIn(text)
while index >= 0:
length = rule.pattern.matchedLength()
print("text: " + text + " index: " + str(index) + " pattern: " + rule.pattern.pattern())
self.setFormat(index, length, rule.format)
index = rule.pattern.indexIn(text, index + length)
self.setCurrentBlockState(0)@
-
I have found the cause. The highlighter instance is destroyed when initUI() terminates. This line fixes the problem on line 52:
@ self.myHighlighter = highlighter.Highlighter(codeTextEdit.document())@