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.messageShown

    def 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:
    pass

    class 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())@


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.