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:
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)
All criteria were met: New complete code for wx search and highlight functionality below. It ain't pretty, but it works.
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.
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
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