【问题标题】:How to change the color of certain words in the tkinter text widget?如何更改 tkinter 文本小部件中某些单词的颜色?
【发布时间】:2013-02-09 09:02:27
【问题描述】:

我有一个程序,我想像 Python shell 一样,在输入某些单词时改变它们的颜色。有什么帮助吗?

【问题讨论】:

    标签: python python-3.x tkinter


    【解决方案1】:

    主要思想是将标签应用到您要自定义的文本部分。您可以使用tag_configure 方法创建具有特定样式的标签,然后只需使用tag_add 方法将此标签应用于要更改的文本部分。 你也可以使用tag_remove的方法移除标签。

    以下是使用tag_configuretag_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()
    

    如果您不知道 sel.firstsel.last 是什么,请查看 this postthis 参考。

    【讨论】:

    • 一点用都没有 - 我似乎无法为文本指定字体颜色
    • 仅凭这些信息,我们无法为您提供帮助。也许提出一个新问题并提供一个示例,我们可以运行并检查您所说的是否属实。
    • 它只有在选择文本并单击Bold按钮后才会起作用,并且不会在用户输入特定单词时立即自动突出显示。但是 OP 想要自动突出显示。可以使用 tkinter 吗?
    • 我想在标签中执行此操作,而不是文本。我得到了这个:'标签'对象没有属性'tag_configure'我怎么能在标签中做到这一点?
    • @DIGMASTER97:你不能在标签中做到这一点。一个标签只有一个前景色和一个背景色。
    【解决方案2】:

    我做了一个聊天客户端。 我使用自定义的非常易于使用的Text 小部件突出显示对话的某些部分,该小部件允许您使用正则表达式应用标签。它基于以下帖子:How to highlight text in a tkinter Text widget

    这里有一个使用示例:

    # "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")
    

    【讨论】:

    • 一个问题AttributeError: 'Text' object has no attribute 'highlight_pattern'
    • 我想在标签中执行此操作,而不是文本。我得到了这个:'标签'对象没有属性'tag_configure'我怎么能在标签中做到这一点?
    【解决方案3】:

    看看这个例子:

    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_add(tagname, startindex[,endindex] ...) 此方法标记由 startindex 定义的位置,或由位置 startindex 和 endindex 分隔的范围。
    • 问题在于 1.8 和 1.13 是文本所在的位置,我希望它在文本出现时改变颜色
    【解决方案4】:

    我能够使用自定义 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
    

    然后,像这样使用它:

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

    【讨论】:

      猜你喜欢
      • 2015-06-12
      • 2021-09-16
      • 2022-12-03
      • 2019-03-26
      • 1970-01-01
      • 2011-05-18
      • 1970-01-01
      • 2018-12-29
      相关资源
      最近更新 更多