Как изменить цвет определенных слов в текстовом виджете tkinter?
У меня есть программа, в которой я хочу быть похожим на оболочку python и изменять цвет определенных слов, когда они набирают какую-либо помощь?
3 ответа
Основная идея - применить теги к частям текста, которые вы хотите настроить. Вы можете создать свои теги, используя метод tag_configure
с определенным стилем, а затем вам просто нужно применить этот тег к части текста, который вы хотите изменить с помощью метода tag_add
, Вы также можете удалить теги, используя метод tag_remove
,
Ниже приведен пример, который использует tag_configure
, tag_add
а также tag_remove
методы.
#!/usr/bin/env python3
import tkinter as tk
from tkinter.font import Font
class Pad(tk.Frame):
def __init__(self, parent, *args, **kwargs):
tk.Frame.__init__(self, parent, *args, **kwargs)
self.toolbar = tk.Frame(self, bg="#eee")
self.toolbar.pack(side="top", fill="x")
self.bold_btn = tk.Button(self.toolbar, text="Bold", command=self.make_bold)
self.bold_btn.pack(side="left")
self.clear_btn = tk.Button(self.toolbar, text="Clear", command=self.clear)
self.clear_btn.pack(side="left")
# Creates a bold font
self.bold_font = Font(family="Helvetica", size=14, weight="bold")
self.text = tk.Text(self)
self.text.insert("end", "Select part of text and then click 'Bold'...")
self.text.focus()
self.text.pack(fill="both", expand=True)
# configuring a tag called BOLD
self.text.tag_configure("BOLD", font=self.bold_font)
def make_bold(self):
# tk.TclError exception is raised if not text is selected
try:
self.text.tag_add("BOLD", "sel.first", "sel.last")
except tk.TclError:
pass
def clear(self):
self.text.tag_remove("BOLD", "1.0", 'end')
def demo():
root = tk.Tk()
Pad(root).pack(expand=1, fill="both")
root.mainloop()
if __name__ == "__main__":
demo()
Если вы не знаете, что sel.first
а также sel.last
есть, проверьте этот пост или эту ссылку.
Я сделал чат-клиент. Я выделил некоторые части разговора, используя пользовательский довольно простой в использовании Text
виджет, который позволяет применять теги с помощью регулярных выражений. Это было основано на следующем посте: Как выделить текст в текстовом виджете tkinter.
Вот вам пример использования:
# "text" is a Tkinter Text
# configuring a tag with a certain style (font color)
text.tag_configure("red", foreground="red")
# apply the tag "red"
text.highlight_pattern("word", "red")
Посмотрите на этот пример:
from tkinter import *
root = Tk()
text = Text(root)
text.insert(INSERT, "Hello, world!\n")
text.insert(END, "This is a phrase.\n")
text.insert(END, "Bye bye...")
text.pack(expand=1, fill=BOTH)
# adding a tag to a part of text specifying the indices
text.tag_add("start", "1.8", "1.13")
text.tag_config("start", background="black", foreground="yellow")
root.mainloop()
Извини, друг! Вы можете изменить шрифты и другие элементы текстового виджета с помощью tag_config, но цвет, который я пробовал, не удался.
text.tag_configure ("warning", fg = "yellow") _tkinter.tclError: растровое изображение "yellow" не определено p
Я смог изменить цвет текста для каждого совпадения регулярного выражения, используя пользовательский текст виджета tkinter, чтобы получить событие, похожее на 'text_changed':
import tkinter as tk
class CustomText(tk.Text):
def __init__(self, *args, **kwargs):
"""A text widget that report on internal widget commands"""
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
А затем используйте это так:
scr = CustomText(w)
scr.tag_configure('red', foreground = 'red')
scr.tag_configure('purple', foreground = '#a820a1')
scr.bind('<<TextModified>>', self.__textchanged__)
def __textchanged__(self, evt):
for tag in evt.widget.tag_names():
evt.widget.tag_remove(tag, '1.0', 'end')
lines = evt.widget.get('1.0', 'end-1c').split('\n')
for i, line in enumerate(lines):
self.__applytag__(i, line, 'red', 'while|if', evt,widget) # your tags here
self.__applytag__(i, line, 'purple', 'True', evt.widget) # with a regex
@staticmethod
def __applytag__ (line, text, tag, regex, widget):
indexes = [(m.start(), m.end()) for m in re.finditer(regex, text)]
for x in indexes:
widget.tag_add(tag, f'{line+1}.{x[0]}', f'{line+1}.{x[1]}')