2

好的,让我们直奔主题。我有 2 个问题
1. 为什么 self.StyleSetSpec(stc.STC_STYLE_DEFAULT, "fore:#000000" + FontSet) 不起作用?
2. 为什么没有应用自定义词法分析器?

这是源代码

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

如果我改变

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

进入

self.SetLexer(stc.STC_LEX_CPP)

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

进入

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

评论突出显示有效。所以错误应该在self.SetLexer(wx.NewId(), STC_LEX_VOTONUSA)STC_LEX_VOTONUSA.STC_VOTONUSA_COMMENT

提前致谢。希望很快能看到一些答案。

4

1 回答 1

3

昨天刚遇到同样的问题,这是我的结果。希望还为时不晚:)

首先,我将词法分析器设置为这个,并像你一样设置内部词法分析器:

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

绑定到事件和 OnStyle 方法是相同的。

而且我将样式的 ID从 1 更改wx.newId()为仅从 1 开始的数字。没有它,我根本看不到任何样式。也stc.STC_STYLE_DEFAULT开始工作了。

完整清单:

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()
于 2012-06-26T08:03:07.913 回答