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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 12:25:55  来源:igfitidea点击:

How to change the color of certain words in the tkinter text widget?

pythonpython-3.xtkinter

提问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_addtag_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.

如果你不知道什么是sel.firstsel.last是,看看这个职位参考。

回答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]}')