[Tkinter-discuss] Text() highlight

Vasilis Vlachoudis Vasilis.Vlachoudis at cern.ch
Mon Aug 25 16:15:59 CEST 2014


Hi all,

I am trying to implement a small g-code editor and real time viewer in tkinter.
I am using the Text() widget as an editor, but I have troubles
in highlighting the text during editing. Its slow when editing big files.

below is the highlighting routine

The routine is scanning for all patterns and picks the next one to highlight
(found dictionary). It assigns a tag and re-scans all the tags that
became invalid (falling within the area of the the just assigned tag.
e.g. a valid command inside a comment)

Running it on the whole text file on every modification is out of the question,
it makes the editing very very slow on big files.

In order to minimize the calls, I do them with a delay of 50ms, using the after()
command during a period of inactivity and only for the 100lines following
the first one to be displayed. Still is slow and lacks interactivity.

I  would like your suggestions, on what is the best way to do the highlighting
during the editing of the code?

Thanks in advance
Vasilis


     def highlight(self):
        self._highAfter = None
        # List contains order of match with regular expression
        patterns = {"C": (r"\(.*\)",              "Blue")    ,
                "X": (r"[xX][+\-]?\d*\.?\d*", "DarkRed"  ),
                "Y": (r"[yY][+\-]?\d*\.?\d*", "DarkBlue" ),
                "Z": (r"[zZ][+\-]?\d*\.?\d*", "DarkGreen"),

                "I": (r"[iI][+\-]?\d*\.?\d*", "Maroon"),
                "J": (r"[jJ][+\-]?\d*\.?\d*", "Maroon"),
                "K": (r"[kK][+\-]?\d*\.?\d*", "Maroon"),
                "R": (r"[rR][+\-]?\d*\.?\d*", "Maroon"),

                "G": (r"[gG]\d+",             "Dark Orchid"),
                "M": (r"[mM]\d+",             "DarkGrey"),
                "F": (r"[fF][+\-]?\d*\.?\d*", "Yellow4"),
                "P": (r"[pP]\d+",             "DarkGrey") }

        for tag in patterns.keys():
            self.editor.tag_delete(tag)

        count = IntVar()
        start = self.editor.index("%d.0"%(self._highStart))
        end   = self.editor.index("%d.0"%(self._highStart+100))

        # First search for the first occurance of all patterns
        found = {}
        for tag,(pat,color) in patterns.items():
            index = self.editor.search(pat, start, end, count=count, regexp=True)
            if index != "":
                found[tag] = (index, count.get())
                #print "Found:", tag, index, count.get()

        # Main loop
        while True:
            # Find the top-most pattern to highlight
            nextTag   = None
            nextIndex = end
            nextCount = 0
            for tag,(index,c) in found.items():
                if self.editor.compare(index,"<",nextIndex):
                    nextTag   = tag
                    nextIndex = index
                    nextCount = c

            #print "Minimum:", nextTag, nextIndex, nextCount
            if nextTag is None: break
            start = self.editor.index("%s+%sc"%(nextIndex,nextCount))
            self.editor.tag_add(nextTag, nextIndex, start)

            # Update tags
            foundItems = found.items()
            for tag,(index,c) in foundItems:
                #print ">>",tag,index
                if self.editor.compare(index,"<",start):
                    index = self.editor.search(patterns[tag][0],
                            start, end,
                            count=count,
                            regexp=True)
                    if index != "":
                        #print "Update:", tag, index, count.get()
                        found[tag] = (index, count.get())
                    else:
                        #print "Update:", tag, "-None-"
                        del found[tag]

        # Set properties to tags
        for tag,(pat,color) in patterns.items():
            self.editor.tag_config(tag,foreground=color)

    # ----------------------------------------------------------------------
    def highlightAfter(self):
        if self._highAfter is not None: self.after_cancel(self._highAfter)
        self._highAfter = self.after(10, self.highlight)

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/tkinter-discuss/attachments/20140825/1961befb/attachment.html>


More information about the Tkinter-discuss mailing list