I've used this question but can't seem to do it again later. I call it with root.after
later but then it does nothing.
my code is:
class CustomText(tk.Text):
'''A text widget with a new method, highlight_pattern()
example:
text = CustomText()
text.tag_configure("red", foreground="#ff0000")
text.highlight_pattern("this should be red", "red")
The highlight_pattern method is a simplified python
version of the tcl code at http://wiki.tcl.tk/3246
'''
def __init__(self, *args, **kwargs):
tk.Text.__init__(self, *args, **kwargs)
def highlight_pattern(self, pattern, tag, start="1.0", end="end",
regexp=False):
'''Apply the given tag to all text that matches the given pattern
If 'regexp' is set to True, pattern will be treated as a regular
expression according to Tcl's regular expression syntax.
'''
start = self.index(start)
end = self.index(end)
self.mark_set("matchStart", start)
self.mark_set("matchEnd", start)
self.mark_set("searchLimit", end)
count = tk.IntVar()
while True:
index = self.search(pattern, "matchEnd","searchLimit",
count=count, regexp=regexp)
if index == "": break
if count.get() == 0: break # degenerate pattern which matches zero-length strings
self.mark_set("matchStart", index)
self.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
self.tag_add(tag, "matchStart", "matchEnd")
root = Tk()
T = CustomText(root).pack()
T.tag_configure("red",foreground="#ff0000")
def highlighttext():
T.highlight_pattern('hello', 'red')
root.after(10, highlighttext)
root.after(10, highlighttext)
root.mainloop()
Thanks for the help.
widget.pack()
returns None, so your T
variable will be None. You need to pack your widget after initialization.higlighttext
doesn't exist, fix your after
method inside the highlighttext
method.highlighttext
method.Highlighting words with after
method seems inefficient and it may not work as expected. Most of the code editors out there make use of the Text Modified events generated by text widgets.
The code for <<TextModified>>
event below is taken from Bryan Oakley's answer to one of the previous questions asked in stackoverflow.
import tkinter as tk
class CustomText(tk.Text):
"""A text widget with a new method, highlight_pattern()
The highlight_pattern method is a simplified python
version of the tcl code at http://wiki.tcl.tk/3246"""
def __init__(self, *args, **kwargs):
tk.Text.__init__(self, *args, **kwargs)
# create a proxy for the underlying widget
self._orig = self._w + "_orig"
self.tk.call("rename", self._w, self._orig)
self.tk.createcommand(self._w, self._proxy)
def _proxy(self, command, *args):
cmd = (self._orig, command) + args
result = self.tk.call(cmd)
if command in ("insert", "delete", "replace"):
self.event_generate("<<TextModified>>")
return result
def highlight_pattern(self, pattern, tag, start="1.0", end="end", regexp=False):
"""Apply the given tag to all text that matches the given pattern
If 'regexp' is set to True, pattern will be treated as a regular
expression according to Tcl's regular expression syntax."""
start = self.index(start)
end = self.index(end)
self.mark_set("matchStart", start)
self.mark_set("matchEnd", start)
self.mark_set("searchLimit", end)
count = tk.IntVar()
while True:
index = self.search(pattern, "matchEnd","searchLimit",
count=count, regexp=regexp)
if index == "": break
# degenerate pattern which matches zero-length strings
if count.get() == 0: break
self.mark_set("matchStart", index)
self.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
self.tag_add(tag, "matchStart", "matchEnd")
root = tk.Tk()
text = CustomText()
text.pack()
text.tag_configure("red", foreground="#ff0000")
def highlighttext(*args):
text.highlight_pattern("hello", "red")
text.bind("<<TextModified>>", highlighttext)
root.mainloop()
With all the fixes applied, your code would look as following
import tkinter as tk
class CustomText(tk.Text):
'''A text widget with a new method, highlight_pattern()
The highlight_pattern method is a simplified python
version of the tcl code at http://wiki.tcl.tk/3246'''
def __init__(self, *args, **kwargs):
tk.Text.__init__(self, *args, **kwargs)
def highlight_pattern(self, pattern, tag, start="1.0", end="end",
regexp=False):
'''Apply the given tag to all text that matches the given pattern
If 'regexp' is set to True, pattern will be treated as a regular
expression according to Tcl's regular expression syntax.
'''
start = self.index(start)
end = self.index(end)
self.mark_set("matchStart", start)
self.mark_set("matchEnd", start)
self.mark_set("searchLimit", end)
count = tk.IntVar()
while True:
index = self.search(pattern, "matchEnd","searchLimit",
count=count, regexp=regexp)
if index == "": break
if count.get() == 0: break # degenerate pattern which matches zero-length strings
self.mark_set("matchStart", index)
self.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
self.tag_add(tag, "matchStart", "matchEnd")
root = tk.Tk()
T = CustomText(root)
T.pack()
T.tag_configure("red",foreground="#ff0000")
def highlighttext():
T.highlight_pattern('hello', 'red')
root.after(1000, highlighttext)
highlighttext()
root.mainloop()