PyQt4でシンタックスハイライト


PyQtでテキストの色分け表示をする方法を調べた。

次のページを参考にした。


http://doc.trolltech.com/qq/qq21-syntaxhighlighter.html



とりあえず、Pythonの3連クオテーションの文字列をハイライトした。

だが、長いテキストになると反応が鈍く、実用にはならない。

もっといい方法があるのだろうか?

import sys
import re
from PyQt4 import QtCore, QtGui

#==============================================================================

class Highlighter(QtGui.QSyntaxHighlighter):
    Normal, InDq3String, InSq3String = xrange(-1, 2)
    
    def __init__(self, document):
        QtGui.QSyntaxHighlighter.__init__(self, document)
        pat &#061; "|".join([r"(?P<SQ3>''')",r'(?P<DQ3>""")'])

        self.re = re.compile(pat)
        
    def highlightBlock(self, text):
        state = self.previousBlockState()
        p = 0
        text = unicode(text)
        for m in self.re.finditer(text):
            if state == self.Normal:
                p = m.start()
                if m.group("SQ3"):
                    state = self.InSq3String
                else:
                    state = self.InDq3String
            elif state == self.InSq3String:
                if m.group("SQ3"):
                    self.setFormat(p, m.end("SQ3") - p, QtGui.QColor("#0000FF"))
                    p = m.end("SQ3")
                    state = self.Normal
            elif state == self.InDq3String:
                if m.group("DQ3"):
                    self.setFormat(p, m.end("DQ3") - p, QtGui.QColor("#00FF00"))
                    p = m.end("DQ3")
                    state = self.Normal
        if state == self.InSq3String:
            self.setFormat(p, len(text)- p, QtGui.QColor("#0000FF"))
        elif state == self.InDq3String:
            self.setFormat(p, len(text)- p, QtGui.QColor("#00FF00"))
        self.setCurrentBlockState(state)
        
class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        self.editor = QtGui.QTextEdit()
        self.setCentralWidget(self.editor)
        self.h = Highlighter(self.editor.document())
        
        f = r"C:\Python26\lib\decimal.py"
        with open(f, "rU") as fp:
            self.editor.setPlainText(unicode(fp.read()))

def main():
    app = QtGui.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    window.resize(640, 512)
    sys.exit(app.exec_())

#==============================================================================

if __name__ == "__main__":
    main()