so i was trying out tkinter Text widget.. and made a small code that highlights the word “print” in the text.. CODE:
JavaScript
x
24
24
1
from tkinter import *
2
def get(*arg):
3
print("Highlighting...")
4
text.tag_remove('found', '1.0', END)
5
s = "print"
6
if s:
7
idx = '1.0'
8
while 1:
9
idx = text.search(s, idx, nocase=1, stopindex=END)
10
if not idx: break
11
lastidx = '%s+%dc' % (idx, len(s))
12
text.tag_add('found', idx, lastidx)
13
idx = lastidx
14
text.see(idx) # Once found, the scrollbar automatically scrolls to the text
15
text.bind('<<Modified>>', get)
16
break
17
text.tag_config('found', foreground='green')
18
19
root = Tk()
20
text = Text(root)
21
text.grid()
22
root.bind('<<Modified>>', get)
23
root.mainloop()
24
In this, the root.bind('<<Modified>>', get)
works only once.
i checked it with the line print("Highlighting...")
it just worked once even when i enter thousands of characters..
Am i doing something wrong? or my approach is bad?
JavaScript
1
5
1
SPECS:
2
OS: Windows 7 SP1 (i will upgrade only to windows 11)
3
Python: Python 3.8.10
4
Arch: Intel x86
5
Advertisement
Answer
Try this:
JavaScript
1
44
44
1
from tkinter import *
2
3
# From: https://stackoverflow.com/a/40618152/11106801
4
class CustomText(Text):
5
def __init__(self, *args, **kwargs):
6
"""A text widget that report on internal widget commands"""
7
Text.__init__(self, *args, **kwargs)
8
9
# create a proxy for the underlying widget
10
self._orig = self._w + "_orig"
11
self.tk.call("rename", self._w, self._orig)
12
self.tk.createcommand(self._w, self._proxy)
13
14
def _proxy(self, command, *args):
15
cmd = (self._orig, command) + args
16
result = self.tk.call(cmd)
17
18
if command in ("insert", "delete", "replace"):
19
self.event_generate("<<TextModified>>")
20
21
return result
22
23
24
def get(event):
25
text.tag_remove("found", "1.0", "end")
26
string = "print"
27
if string:
28
idx = "1.0"
29
while True:
30
idx = text.search(string, idx, nocase=1, stopindex=END)
31
if not idx:
32
break
33
lastidx = f"{idx}+{len(string)}c"
34
text.tag_add("found", idx, lastidx)
35
idx = lastidx
36
text.tag_config("found", foreground="green")
37
38
39
root = Tk()
40
text = CustomText(root)
41
text.grid()
42
root.bind("<<TextModified>>", get)
43
root.mainloop()
44
This uses the CustomText
that @BryanOakley created here.
Also I had to remove the break
from the end of your while True
loop because it stopped searching for "print"
.