StyledTextCtrl.GetStyledText() returns random data?

So nice!
In my use case, I wanted to highlight the searched words with a bold, yellow foreground, and red background. But I couldn’t find a way to do it and finally gave up… :worried:

Now, I’m using an indicator to do that but my complaint is that the color is half transparent and not so vibrant. So, I really appreciate it if you would give me a code snippet to achieve this! :star_struck:

I posted a sample code that uses stc indicater to make word clickable two months ago
(Notebook word make clickable - #12 by komoto48g).
The following is a bit modified version:

import wx
from wx import stc

class TestEditor(stc.StyledTextCtrl):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        
        self.StyleSetSpec(stc.STC_STYLE_DEFAULT,
                          "fore:#cccccc,back:#202020,face:MS Gothic,size:9")
        self.StyleClearAll()
        
        ## context-base style
        if wx.VERSION < (4,1,0):
            self.IndicatorSetStyle(0, stc.STC_INDIC_PLAIN)
            self.IndicatorSetStyle(1, stc.STC_INDIC_CONTAINER)
        else:
            self.IndicatorSetStyle(0, stc.STC_INDIC_TEXTFORE)
            self.IndicatorSetStyle(1, stc.STC_INDIC_ROUNDBOX)
        self.IndicatorSetForeground(0, "red")
        self.IndicatorSetForeground(1, "yellow")
        
        if wx.VERSION >= (4,1,0):
            self.IndicatorSetHoverStyle(1, stc.STC_INDIC_ROUNDBOX)
            self.IndicatorSetHoverForeground(1, "blue")
        
        self.Bind(stc.EVT_STC_INDICATOR_CLICK, self.OnIndicator)
    
    def OnIndicator(self, evt):
        if self.IndicatorValue == 1:
            p = self.IndicatorStart(1, evt.Position)
            q = self.IndicatorEnd(1, evt.Position)
            print(self.GetTextRange(p, q))
    
    def FilterText(self, text):
        if not text:
            for i in range(2):
                self.SetIndicatorCurrent(i)
                self.IndicatorClearRange(0, self.TextLength)
            return
        word = text.encode() # for multi-byte string
        raw = self.TextRaw # for multi-byte string
        lw = len(word)
        pos = -1
        while 1:
            pos = raw.find(word, pos+1)
            if pos < 0:
                break
            for i in range(2):
                self.SetIndicatorCurrent(i)
                self.IndicatorFillRange(pos, lw)

samplePhrase = """
She sells sea shells by the seashore.
The shells that she sells are sea shells I'm sure.
So if she sells sea shells on the seashore,
I'm sure that the shells are seashore shells.
"""

if __name__ == "__main__":
    app = wx.App()
    frame = wx.Frame(None)
    ed = TestEditor(frame)
    ed.Text = samplePhrase
    ed.FilterText("shells")
    frame.Show()
    app.MainLoop()

image I hope it will work on Linux.