wxPython StyleSetSpec and SetLexer not working?
Question: Ok, let's get straight to the point. I got 2 questions  
1\. Why self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "fore:#000000" + FontSet) not
working?  
2\. Why the custom lexer is not applied?  

This is the source code

    
    
    import wx, re, keyword
    from wx import stc
    
    class BaseLexer(object):
      """Defines simple interface for custom lexer objects"""
      def __init__(self):
        super(BaseLexer, self).__init__()
    
      def StyleText(self, event):
        raise NotImplementedError
    
    class STC_LEX_VOTONUSA(BaseLexer):
      # Define some style IDs
      STC_VOTONUSA_DEFAULT = wx.NewId()
      STC_VOTONUSA_VALUE = wx.NewId()
      STC_VOTONUSA_OBJECT = wx.NewId()
      STC_VOTONUSA_TYPE = wx.NewId()
      STC_VOTONUSA_OPERATION = wx.NewId()
      STC_VOTONUSA_COMMENT =wx.NewId()
      STC_VOTONUSA_QUALIFIER = wx.NewId()
    
      def __init__(self):
        super(STC_LEX_VOTONUSA, self).__init__()
        # Attributes
        self.Comment = re.compile("""
         //
         """, re.X)
        self.Types = re.compile("""
         \\b
         (void|integer|shortint|(short)?word|float|boolean|char|record|program|module)
         \\b
         """, re.I|re.X)
        self.Operation = re.compile("""
         (read|write)(line)?|if|main|case|while|use|return|exit|in_case|repeat_until
         (\+|-|\*|/|%|\*\*|:|!|<|>)?=?|
         (\{|\}|\(|\)|\[|\])
         """, re.I|re.X)
        self.Value = re.compile("""
         [(`\d*)+\'\w*\']*|\'.*\'|[\+-]*\d*\.?\d*
         """, re.I|re.X)
        self.Qualifier = re.compile("""
         interface|implementation
         """, re.I|re.X)
        self.Object = re.compile("""
         s
         """, re.I|re.X)
    
      def GetLastWord(self, Line, CaretPos):
        """
        Get the last word from a line
        """
        LastWord = re.search(
         """
         \s*
         (
          ".*"|                           # String data type
          \w*|                            # Any letter/number
          (\+|-|\*|/|%|\*\*|:|!|<|>)?=?|  # Assignment, Comparison & Mathematical
          (\{|\}|\(|\)|\[|\])             # Brackets
         )
         \s*\Z
         """,
         Line[:CaretPos], re.VERBOSE)
        return LastWord
    
      def StyleText(self, event):
        """Handle the EVT_STC_STYLENEEDED event"""
        Obj = event.GetEventObject()
    
        # Get Last Correctly Styled
        LastStyledPos = Obj.GetEndStyled()
    
        # Get Styling Range
        Line = Obj.LineFromPosition(LastStyledPos)
        StartPos = Obj.PositionFromLine(Line)
        EndPos = event.GetPosition()
    
        # Walk the Range and Style Them
        while StartPos < EndPos:
          Obj.StartStyling(StartPos, 0x1f)
          LastWord = self.GetLastWord(Line, CaretPos)
          if self.Comment.search(LastWord):
            # Set Comment Keyword style
            Style = self.STC_VOTONUSA_COMMENT
          elif self.Type.search(LastWord):
            # Set Type Keyword style
            Style = self.STC_VOTONUSA_TYPE
          elif self.Operation.search(LastWord):
            # Set Operation Keyword style
            Style = self.STC_VOTONUSA_OPERATION
          elif self.Value.search(LastWord):
            # Set Value Keyword style
            Style = self.STC_VOTONUSA_VALUE
          elif self.Qualifier.search(LastWord):
            # Set Qualifier Keyqord style
            Style = self.STC_VOTONUSA_QUALIFIER
          elif self.Object.search(LastWord):
            # Set Object Keyword style
            Style = self.STC_VOTONUSA_OBJECT
          # Set the styling byte information for length of LastWord from
          # current styling position (StartPos) with the given style.
          Obj.SetStyling(len(LastWord), Style)
          StartPos += len(LastWord)
    
    class CustomSTC(stc.StyledTextCtrl):
      def __init__(self, parent):
        super(CustomSTC, self).__init__(parent)
        # Attributes
        self.custlex = None
        Font = wx.Font(12, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
        Face = Font.GetFaceName()
        Size = Font.GetPointSize()
    
        # Setup
        kwlist = u" ".join(keyword.kwlist)
        self.SetKeyWords(0, kwlist)
        self.StyleClearAll()
        self.SetLexer(wx.NewId(), STC_LEX_VOTONUSA)
        self.EnableLineNumbers()
        FontSet = "face:%s, size:%d" % (Face, Size)
    
        self.StyleSetSpec(stc.STC_STYLE_LINENUMBER, FontSet)
        # Set Default to Black
        self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "fore:#000000" + FontSet)
        # Set Comment to Pink
        self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_COMMENT, "fore:#ff007f" + FontSet)
        # Set Value to Green
        self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_VALUE, "fore:#00ff00" + FontSet)
        # Set Object to Brown
        self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_OBJECT, "fore:#a52a2a" + FontSet)
        # Set Type to Red
        self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_TYPE, "fore:#ff0000" + FontSet)
        # Set Operation to Blue
        self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_OPERATION, "fore:#0000ff" + FontSet)
        # Set Qualifier to Orange
        self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_QUALIFIER, "fore:#cc3232" + FontSet)
    
        # Event Handlers
        self.Bind(stc.EVT_STC_STYLENEEDED, self.OnStyle)
    
      def EnableLineNumbers(self, enable=True):
        """Enable/Disable line number margin"""
        if enable:
          self.SetMarginType(1, stc.STC_MARGIN_NUMBER)
          self.SetMarginMask(1, 0)
          self.SetMarginWidth(1, 25)
        else:
          self.SetMarginWidth(1, 0)
    
      def OnStyle(self, event):
        # Delegate to custom lexer object if one exists
        if self.custlex:
          self.custlex.StyleText(event)
        else:
          event.Skip()
    
      def SetLexer(self, lexerid, lexer=None):
        """
        Overrides StyledTextCtrl.SetLexer
        Adds optional param to pass in custom container
        lexer object.
        """
        self.custlex = lexer
        super(CustomSTC, self).SetLexer(lexerid)
    
    class NUSAIPT(wx.Frame):
      def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, None, wx.ID_ANY, 'VOTO NUSA IPT')
        self.TextArea = CustomSTC(self)
        self.Show()
    
    app = wx.App()
    frame = NUSAIPT()
    app.MainLoop()
    

If I change

    
    
    self.SetLexer(wx.NewId(), STC_LEX_VOTONUSA)
    

into

    
    
    self.SetLexer(stc.STC_LEX_CPP)
    

and

    
    
    self.StyleSetSpec(STC_LEX_VOTONUSA.STC_VOTONUSA_COMMENT, "fore:#ff007f" + FontSet)
    

into

    
    
    self.StyleSetSpec(stc.STC_C_COMMENT, "fore:#ff007f" + FontSet)
    

the comment highlighting worked. so the mistake should be in
`self.SetLexer(wx.NewId(), STC_LEX_VOTONUSA)` or
`STC_LEX_VOTONUSA.STC_VOTONUSA_COMMENT`

Thanks in advance. Hope to see some answer soon.


Answer: Just stuck with same problem yesterday, here are my results. Hope it's not too
late :)

First, i set lexer to this one, and internal lexer as you do:

    
    
    self.SetLexer(stc.STC_LEX_CONTAINER)
    self.custlex = SCT_LEX_ERLANG_IDNOISE(self)
    

Bind to event and OnStyle method are same.

And also i changed id of styles from `wx.newId()` to just numbers starting
from 1. Without it i didn't see any styling at all. Also
`stc.STC_STYLE_DEFAULT` started to work too.

Full listing:

    
    
    class SCT_LEX_ERLANG_IDNOISE(BaseLexer):
        STC_ERLANG_IDNOISE_DEFAULT = 1
        STC_ERLANG_IDNOISE_VARIABLE = 2
        STC_ERLANG_IDNOISE_ATOM = 3
        STC_ERLANG_IDNOISE_MODULE = 4
        STC_ERLANG_IDNOISE_KEYWORD = 5
        STC_ERLANG_IDNOISE_COMMENT = 6
        STC_ERLANG_IDNOISE_MACROS = 7
        STC_ERLANG_IDNOISE_NUMBER = 8
    
        def __init__(self, control):
            super(SCT_LEX_ERLANG_IDNOISE, self).__init__(control)
            self.typeFormatDict = {}
            self.typeFormatDict["other"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_DEFAULT
            self.typeFormatDict["variable"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_VARIABLE
            self.typeFormatDict["atom"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_ATOM
            self.typeFormatDict["module"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_MODULE
            self.typeFormatDict["keyword"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_KEYWORD
            self.typeFormatDict["comment"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_COMMENT
            self.typeFormatDict["macros"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_MACROS
            self.typeFormatDict["number"] = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_NUMBER
    
        def StyleText(self, event):
            start = self.control.GetEndStyled()
            end = event.GetPosition()
            line = self.control.LineFromPosition(start)
            start = self.control.PositionFromLine(line)
            text = self.control.GetTextRange(start, end)
    
            self.control.StartStyling(start, 0x1f)
            lastEnd = 0
            for type, start, end, value in getHighlightRules(text):
                style = SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_DEFAULT
                if start > lastEnd:
                    self.control.SetStyling(start - lastEnd, style)
                if type in self.typeFormatDict:
                    style = self.typeFormatDict[type]
                self.control.SetStyling(len(value), style)
                lastEnd = end
    
    
    class CustomSTC(stc.StyledTextCtrl):
        def __init__(self, parent):
            super(CustomSTC, self).__init__(parent)
            self.custlex = SCT_LEX_ERLANG_IDNOISE(self)
    
            #self.SetKeyWords(0, kwlist)
    
            self.SetLexer(stc.STC_LEX_CONTAINER)
            self.EnableLineNumbers()
    
            self.StyleSetSpec(stc.STC_STYLE_DEFAULT, ColorSchema.formats["other"])
            self.StyleClearAll()
            self.StyleSetSpec(stc.STC_STYLE_LINENUMBER, ColorSchema.lineFont)
            self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_DEFAULT, ColorSchema.formats["other"])
            self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_VARIABLE, ColorSchema.formats["variable"])
            self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_ATOM, ColorSchema.formats["atom"])
            self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_MODULE, ColorSchema.formats["module"])
            self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_KEYWORD, ColorSchema.formats["keyword"])
            self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_COMMENT, ColorSchema.formats["comment"])
            self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_MACROS, ColorSchema.formats["macros"])
            self.StyleSetSpec(SCT_LEX_ERLANG_IDNOISE.STC_ERLANG_IDNOISE_NUMBER, ColorSchema.formats["number"])
    
            # Event Handlers
            self.Bind(stc.EVT_STC_STYLENEEDED, self.OnStyle)
    
        def EnableLineNumbers(self, enable=True):
            """Enable/Disable line number margin"""
            if enable:
                self.SetMarginType(1, stc.STC_MARGIN_NUMBER)
                self.SetMarginMask(1, 0)
                self.SetMarginWidth(1, 35)
            else:
                self.SetMarginWidth(1, 0)
    
        def OnStyle(self, event):
            if self.custlex:
                self.custlex.StyleText(event)
            else:
                event.Skip()
    

