LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Porting Qt highlighting example code to PyQt4 (https://www.linuxquestions.org/questions/programming-9/porting-qt-highlighting-example-code-to-pyqt4-768959/)

Snouffelaire 11-13-2009 01:09 PM

Porting Qt highlighting example code to PyQt4
 
[Edit]See post #2 for a simplified version of the problem (I think)[/Edit]

Hello everyone,

I'm trying to port the Qt syntax highlighting example to PyQt4 and I am having a few problems. The code seems to work but nothing is highlighted and sometimes (when i try to modify the beginning of a line or the end of a line that should be highlighted), I get stucked in a infinite loop.

Here is the example code :
http://qt.nokia.com/doc/4.0/richtext...ghlighter.html

And here is mine :
Code:

#!/usr/bin/python
# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui


def gimme_my_mappings():
    a = QtGui.QTextCharFormat()
    a.setFontWeight(QtGui.QFont.Bold)
    a.setForeground(QtCore.Qt.blue)

    functionFormat = QtGui.QTextCharFormat()
    functionFormat.setFontItalic(True)
    functionFormat.setForeground(QtCore.Qt.red)

    mappings = {}
    mappings["%[^\n]*"] = a
    mappings["\\b[a-z0-9_]+\\(.*\\)"] = functionFormat
   
    return mappings


def highlight(doc, position, removed, added):
   
    block = doc.findBlock(position)
    print block, doc, position, removed, added

    if not block.isValid():
        print "not valid"
        return None
   
    if added>removed:
        endBlock = doc.findBlock(position+added)
    else:
        endBlock = block
   
    while (block.isValid() and not (endBlock < block)):
        highlightBlock(block)
        block = block.next()


def highlightBlock(block):
    mappings = gimme_my_mappings()
    layout = block.layout()
    text = block.text()
    print text
    overrides = []
   
    for k in mappings.keys():
        expression = QtCore.QRegExp(k)
        i = text.indexOf(expression)
        while i>=0:
            #here is the infinite loop !
            range = QtGui.QTextLayout.FormatRange()
            range.start = i
            range.length = expression.matchedLength()
            range.format = mappings[k]
            overrides.append(range)
            i = text.indexOf(expression, i + expression.matchedLength())
       
    layout.setAdditionalFormats(overrides)
    block.document().markContentsDirty(block.position(), block.length())

These functions are then called from my main application that contains a QTextEdit named textEdit with :
Code:

QtCore.QObject.connect(self.ui_prefs.textEdit.document(),\
    QtCore.SIGNAL("contentsChange(int,int,int)"),self.highlight1)

and :
Code:

def highlight1(self, position, removed, added):
    highlight(self.ui_prefs.textEdit.document(), position, removed, added)


I have re-read the code a thousand times and I can't find what I missed. If anyone has an idea, I'd be happy to hear it !! :)

Thanks !

Snouffelaire 11-14-2009 01:14 AM

Things have changed a little but the problem is the same...

I found out that there was a QSyntaxHighlighter class that sould handle syntax highlighting problems :
http://www.riverbankcomputing.co.uk/...ghlighter.html

I tried making a new app so I would be sure I didn't miss anything and I'm still stuck in an infinite loop... I did copy/paste the example code given on trolltech's site (I mean, I transformed it to Python). I made a Dialog with Designer and pyuic4 it (it is named gui.py) :
Code:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'gui.ui'
#
# Created: Sat Nov 14 07:46:19 2009
#      by: PyQt4 UI code generator 4.4.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(400, 300)
        self.gridLayout = QtGui.QGridLayout(Dialog)
        self.gridLayout.setObjectName("gridLayout")
        self.textEdit = QtGui.QTextEdit(Dialog)
        self.textEdit.setObjectName("textEdit")
        self.gridLayout.addWidget(self.textEdit, 0, 0, 1, 1)
        self.buttonBox = QtGui.QDialogButtonBox(Dialog)
        self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
        self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
        self.buttonBox.setObjectName("buttonBox")
        self.gridLayout.addWidget(self.buttonBox, 1, 0, 1, 1)

        self.retranslateUi(Dialog)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("accepted()"), Dialog.accept)
        QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

    def retranslateUi(self, Dialog):
        Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))

and here is the main application :
Code:

#!/usr/bin/python
# -*- coding: utf-8 -*-

from PyQt4 import QtCore, QtGui
from gui import *

class MyApp(Ui_Dialog):
    def setupUi2(self, Dialog):
        Ui_Dialog.setupUi(self, Dialog)
        self.highlighter = MyHighlighter(self.textEdit)


class MyHighlighter(QtGui.QSyntaxHighlighter):
    def __init__(self, edit):
        QtGui.QSyntaxHighlighter.__init__(self,edit)
 
    def highlightBlock(self, text):       
        myClassFormat = QtGui.QTextCharFormat()
        myClassFormat.setFontWeight(QtGui.QFont.Bold)
        myClassFormat.setForeground(QtCore.Qt.darkMagenta)
        pattern = "\\b[A-Z_]+\\b"
       
        expression = QtCore.QRegExp(pattern)
        index = text.indexOf(expression);
        while (index >= 0):
            length = expression.matchedLength()
            self.setFormat(index, length, myClassFormat)
            index = text.indexOf(expression, index + length)

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    Dialog = QtGui.QDialog()
    ui = MyApp()
    ui.setupUi2(Dialog)
    Dialog.show()
    sys.exit(app.exec_())

Any help would be greatly appreciated :)

Snouffelaire 11-17-2009 06:56 AM

Ok, I finally found an answer... I forgot this little line :
Code:

self.highlighter.setDocument(self.textEdit.document())
that should be added in the setupUI2 function.

Hope this will help someone in the future !

Snouffelaire 11-17-2009 12:28 PM

I actually found out that this was never the problem... I just need to update PyQt4 as I still get stuck in the loop with version 4.4.4. and not with the version I have at work.

Edit : the version I have at work is 4.3.3 so there must be a bug in version 4.4.4. I'm perplex.

Snouffelaire 11-20-2009 12:02 PM

I had an answer to my question on the python usenet group.

If someone has the same problem, here is an answer :
http://groups.google.fr/group/comp.l...fc8b120cb5d686


All times are GMT -5. The time now is 05:48 PM.