'Always tkinter Text highlight_patern not working [closed]
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.
Solution 1:[1]
Fixes
widget.pack()returns None, so yourTvariable will be None. You need to pack your widget after initialization.- A function named
higlighttextdoesn't exist, fix youraftermethod inside thehighlighttextmethod. - Remove the after method outside
highlighttextmethod.
Suggestions
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()
Complete code
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()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Billy |
