Как подсвечивать разными цветами текст в виджете text tkinter?

Рейтинг: 0Ответов: 1Опубликовано: 08.02.2023

Нужно причём чтобы подсвечивались слова которые написал пользователь. К примеру : написал "банан" написанная надпись "банан" начала подсвечиваться жёлтым, написал "яблоко" подвешивается красным. Как это реализовать?

Ответы

▲ 0Принят

Алгоритм такой:

В текстовом поле нужно создать тег - объект, для которого можно указать какие-то свойства (фон, цвет текста, другие свойства шрифта) или, например, назначить реакцию на событие (например, при клике мышью выполнить какое-то действие). Это выполняется через метод текстового поля tag_config.

Дальше этот тег нужно назначить на фрагмент текста, тогда этот фрагмент текста получит свойства, прописанные для этого тега. Это делается через метод tag_add.

Дальше, если нужно подсвечивать по мере ввода, то нужно при каждом изменении текста нужно разбивать его на отдельные слова, каждое слово проверять - нужно его красить или нет, нужным словам назначить соответствующий тег.

Пример кода на основе ответа: Как сделать подсветку синтаксиса в tkinter

Код упрощаем, заменяем разбиение на токены через pygments на выделение слов по простому регулярному выражению, словам через словарь сопоставляем типы тегов.

По мере ввода текст подсвечиваем.

import tkinter as tk
import re

root = tk.Tk()

text = tk.Text(root)
text.pack()

# Создаем теги с разными свойствами, которые будем присваивать соответствующим частям текста
text.tag_config("blue", foreground="blue")
text.tag_config("red", foreground="red")
text.tag_config("yellow", foreground="yellow")

# Прописываем соответствие тексту название тега подсветки (из прописанных выше)
token_to_tag = {
    "банан": "yellow",
    "яблоко": "red",
}


def on_edit(event):
    # Удалить все имеющиеся теги из текста
    for tag in text.tag_names():
        text.tag_remove(tag, 1.0, tk.END)
    
    # Разобрать текст на токены
    s = text.get(1.0, tk.END)
    
    for i, line in enumerate(s.splitlines(), start=1):  # Идем по тексту построчно, считаем номер строки (от 1)
        for match in re.finditer(r"\w+", line):  # Находим в тексте отдельные слова
            token_text = match.group(0).lower()  # lower - чтобы срабатывало, и на банан, и на БаНаН
            start = match.start()
            end = match.end()
            print(start, end, token_text)  # Отладочный вывод
            
            if token_text in token_to_tag:
                # Если слово есть в словаре token_to_tag, добавляем ему тег с нужным цветом из этого словаря
                # Координаты начала-окончания диапазон текста задаются через "номер_строки.индекс_символа"
                text.tag_add(token_to_tag[token_text], f"{i}.{start}", f"{i}.{end}")

    # Сбросить флаг редактирования текста
    text.edit_modified(0)


text.bind('<<Modified>>', on_edit)

root.mainloop()

введите сюда описание изображения