1

I have a TextCtrl which contains various log data, I also have a EditText field whereby the user can search for a string to find, and then click the Find button to locate and highlight the word if it is found in the logs. Your standard Find/highlight in browser/Notepad etc.

The code I have does already work and successfully highlights the user's word, however there are a couple of bits missing that I would like to implement:

  • The ability to search the same word, and have the next word highlighted e.g a 'Find Next' EDIT: This was solved by adding in a 'Find Next' button with the below code. The count limits the next highlight to 1 word rather than all of them to the end of the log.
  • Un-highlight the current word when a new word is searched, be it the same word, or a new word
  • Start the position at 0 (top of the data) if searching a new word EDIT: solved by resetting the startPos value inside the findTxt def

    def findTxt(self,e):
    global wordPos
    newstring = self.logTxt.GetValue()
    for i in range(self.progressBox.GetNumberOfLines()):
        line = self.progressBox.GetLineText(i)
        if newstring in line:
            startPos = self.progressBox.GetValue().find(newstring)
            endPos = startPos + len(newstring) 
            wordPos = endPos
            self.progressBox.Bind(wx.EVT_SET_FOCUS, self.highlightText(startPos, endPos))
            startPos = 0
            self.findNextBtn.Enable() 
    
    def findNext(self,e):
    global wordPos
    newstring = self.logTxt.GetValue()
    count = 0
    for i in range(self.progressBox.GetNumberOfLines()):
        if count == 0: 
            line = self.progressBox.GetValue()
            if newstring in line:
                startPos = self.progressBox.GetValue().find(newstring, wordPos)
                endPos = startPos + len(newstring) 
                wordPos = endPos
                self.progressBox.Bind(wx.EVT_SET_FOCUS, self.highlightText(startPos, endPos))
                count = 1
    
    
    def highlightText(self, pos, size):
    self.progressBox.SetStyle(pos, size, wx.TextAttr("black", "turquoise"))
    self.progressBox.SetInsertionPoint(pos)
    

1 Answer 1

0

All criteria were met: New complete code for wx search and highlight functionality below. It ain't pretty, but it works.

  • The ability to search the same word, and have the next word highlighted e.g a 'Find Next'

EDIT: This was solved by adding in a 'Find Next' button with the below code. The count limits the next highlight to 1 word rather than all of them to the end of the data.

  • Un-highlight the current word when a new word is searched, be it the same word, or a new word

EDIT: solved by creating 2 new global variables that hold the value of old position and length of word, and then recolouring the highlight to black/white before finding new word

  • Start the position at 0 (top of the data) if searching a new word

EDIT: solved by resetting the startPos value inside the findTxt def

global wordPos
wordPos,oldPos = '',''

#wx widgets
self.progressBox = wx.TextCtrl(panelLog, style=wx.TE_MULTILINE|wx.TE_READONLY|wx.TE_RICH2)
    hBox2.Add(self.progressBox, 5, flag=wx.EXPAND)
    vBox.Add(hBox2, 2, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM, border=10)

    self.logTxt = wx.TextCtrl(panelLog, style=wx.TE_RICH)
    hBox3.Add(self.logTxt, 1, flag=wx.LEFT, border=5)

    self.findBtn = wx.Button(panelLog, -1, "Find")
    self.Bind(wx.EVT_BUTTON, self.findTxt, self.findBtn)
    hBox3.Add(self.findBtn, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM, border=3)

    self.findNextBtn = wx.Button(panelLog, -1, "Find Next")
    self.findNextBtn.Disable()
    self.Bind(wx.EVT_BUTTON, self.findNext, self.findNextBtn)
    hBox3.Add(self.findNextBtn, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM, border=3)
    vBox.Add(hBox3, 0, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM, border=10)

#method code
def findTxt(self,e):
    global wordPos, oldPos
    newstring = self.logTxt.GetValue()
    if wordPos:
        self.progressBox.SetStyle(oldPos, wordPos, wx.TextAttr("black", "white"))
    for i in range(self.progressBox.GetNumberOfLines()):
        line = self.progressBox.GetLineText(i)
        if newstring in line:
            startPos = self.progressBox.GetValue().find(newstring)
            endPos = startPos + len(newstring) 
            wordPos = endPos
            oldPos = startPos

            self.progressBox.Bind(wx.EVT_SET_FOCUS, self.highlightText(startPos, endPos))
            startPos = 0
            self.findNextBtn.Enable()


def findNext(self,e):
    global wordPos, oldPos
    newstring = self.logTxt.GetValue()
    self.progressBox.SetStyle(oldPos, wordPos, wx.TextAttr("black", "white"))
    count = 0
    for i in range(self.progressBox.GetNumberOfLines()):
        if count == 0: 
            line = self.progressBox.GetValue()
            if newstring in line:
                startPos = self.progressBox.GetValue().find(newstring, wordPos)
                endPos = startPos + len(newstring) 
                wordPos = endPos
                oldPos = startPos
                self.progressBox.Bind(wx.EVT_SET_FOCUS, self.highlightText(startPos, endPos))
                count = 1
Sign up to request clarification or add additional context in comments.

1 Comment

Anyone ending up here might also appreciate to look at the wx.FindReplaceDialog as explained here.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.