python tkinter textbox Wörter markieren?
Ich habe mit Python und tkinter eine textbox programmiert.
Nun möchte ich, das immer wenn jemand das Wort Hallo schreibt es blau wird.
Jedes andere Wort bleibt normal außer wenn man Hallo schreibt soll es blau werden.
Wie kriege ich das hin?
2 Antworten
Eine Lösung könnte so aussehen:
#!/usr/bin/env python3
import re
import tkinter as tk
class HighlighterTextbox(tk.Text):
def __init__(self, *master, word_to_highlight="", **options):
tk.Text.__init__(self, *master, **options)
self.clear_modified_flag()
self.bind("<<Modified>>", self.has_been_modified)
self.tag_configure("HIGHLIGHTED", foreground="blue")
self.word_to_highlight = word_to_highlight
def clear_modified_flag(self):
self.reset_modified_currently = True
try:
self.tk.call(self._w, "edit", "modified", 0)
finally:
self.reset_modified_currently = False
def has_been_modified(self, event=None):
if self.reset_modified_currently:
return
self.clear_modified_flag()
self.on_modified(event)
def on_modified(self, event=None):
text = self.get("1.0", "end-1c")
matches = re.finditer(self.word_to_highlight, text)
for match in matches:
self.tag_add("HIGHLIGHTED", "1.0+" + str(match.start()) + "c", "1.0+" + str(match.end()) + "c")
class TextPad(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.textfield = HighlighterTextbox(self, word_to_highlight="Hello")
self.textfield.focus()
self.textfield.pack(fill="both", expand=True)
if __name__ == "__main__":
root = tk.Tk()
TextPad(root).pack(expand=1, fill="both")
root.mainloop()
Ich werde die Lösung nur grob beschreiben.
Zunächst wird eine eigene Textbox-Klasse angelegt, die von Tk.Text erbt. In dieser wird das Modified-Event an die Box (bzw. den Handler has_been_modified) gebunden, sodass auf jede Änderung reagiert werden kann. Allerdings setzt die Standardtextbox nach einer Änderung einen internen Flag (modified), der sich folgend nicht wieder selbst aktualisiert und somit verhindert, dass der gebundene Handler bei jeder Änderung aufgerufen werden kann. Daher wird der interne Flag nach jeder Modifikation manuell zurückgesetzt. Um zu verhindern, dass deswegen der eigene Handler mehrmals aufgerufen wird (das Zurücksetzen triggert ebenso das Modified-Event ein erneutes Mal), wird der reset_modified_currently-Flag als Blocker verwendet.
In on_modified wird die Logik formuliert, die den Text kennzeichnen soll. Dafür wird der Text geholt und alle Vorkommen des gesuchten Wortes werden ermittelt. Die Positionen dieser Vorkommen werden mit einem Tag ausgestattet, der die blaue Schriftfarbe definiert. Beim Löschen von Buchstaben werden die Wörter aber noch nicht aktualisiert. Das wäre etwas, was man sich als Nächstes anschauen könnte. Ebenso könnte man sicherlich verhindern, dass mit jeder Textänderung die Tags neu zur Textbox zugefügt werden.
Die Textbox wird zuguter Letzt in ein Fenster / Frame eingebettet.
Wenn du nun noch nach detaillierten Informationen zu einzelnen Funktionen suchst, kannst du diese aus der Dokumentation oder von Effbot beziehen. Anpassungen und Erweiterungen überlasse ich gänzlich dir.
Ich würde sagen, dass das nicht 100% möglich ist.
Schau dir mal das hier an, vielleicht kommt es dem ja nahe, was du willst :)
https://www.geeksforgeeks.org/change-the-color-of-certain-words-in-the-tkinter-text-widget/