Python 如何更改 tkinter 文本小部件中某些单词的颜色?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14786507/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to change the color of certain words in the tkinter text widget?
提问by Arctoran
I have a program that I want to be like the Python shell and change color of certain words when they are typed. Any help?
我有一个程序,我希望它像 Python shell 一样,并在键入时更改某些单词的颜色。有什么帮助吗?
采纳答案by nbro
The main idea is to apply tagsto the parts of text you want to customise. You can create your tags using the method tag_configure, with a specific style, and then you just need to apply this tag to the part of text you want to change using the method tag_add.
You can also remove the tags using the method tag_remove.
主要思想是将标签应用于要自定义的文本部分。您可以使用方法创建tag_configure具有特定样式的标签,然后只需将此标签应用于要使用方法更改的文本部分tag_add。您还可以使用 方法删除标签tag_remove。
The following is an example that uses tag_configure, tag_addand tag_removemethods.
以下是使用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()
If you don't know what sel.firstand sel.lastare, check out this postor thisreference.
回答by Adem ?zta?
Have a look at this example:
看看这个例子:
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()
回答by Rnhmjoj
I have made a chat client.
I highlighted certain parts of the conversation using a custom quite easy to use Textwidget that allows you to apply tags using regular expressions. It was based on the following post: How to highlight text in a tkinter Text widget.
我做了一个聊天客户端。我使用自定义的非常易于使用的Text小部件突出显示了对话的某些部分,该小部件允许您使用正则表达式应用标签。它基于以下帖子:如何在 tkinter 文本小部件中突出显示文本。
Here you have an example of use:
这里有一个使用示例:
# "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")
回答by Vinícius Gabriel
I was able to change the color of the text for every match of a regex using the custom tkinter widget Text to get an event similiar to a 'text_changed':
我能够使用自定义 tkinter 小部件 Text 为正则表达式的每个匹配更改文本的颜色,以获得类似于“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
And then, use it like that:
然后,像这样使用它:
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]}')

