so i was trying out tkinter Text widget.. and made a small code that highlights the word “print” in the text.. CODE:
from tkinter import * def get(*arg): print("Highlighting...") text.tag_remove('found', '1.0', END) s = "print" if s: idx = '1.0' while 1: idx = text.search(s, idx, nocase=1, stopindex=END) if not idx: break lastidx = '%s+%dc' % (idx, len(s)) text.tag_add('found', idx, lastidx) idx = lastidx text.see(idx) # Once found, the scrollbar automatically scrolls to the text text.bind('<<Modified>>', get) break text.tag_config('found', foreground='green') root = Tk() text = Text(root) text.grid() root.bind('<<Modified>>', get) root.mainloop()
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?
SPECS: OS: Windows 7 SP1 (i will upgrade only to windows 11) Python: Python 3.8.10 Arch: Intel x86
Advertisement
Answer
Try this:
from tkinter import * # From: https://stackoverflow.com/a/40618152/11106801 class CustomText(Text): def __init__(self, *args, **kwargs): """A text widget that report on internal widget commands""" 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 get(event): text.tag_remove("found", "1.0", "end") string = "print" if string: idx = "1.0" while True: idx = text.search(string, idx, nocase=1, stopindex=END) if not idx: break lastidx = f"{idx}+{len(string)}c" text.tag_add("found", idx, lastidx) idx = lastidx text.tag_config("found", foreground="green") root = Tk() text = CustomText(root) text.grid() root.bind("<<TextModified>>", get) root.mainloop()
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"
.