如何在 tkinter Text 小部件中突出显示文本

Posted

技术标签:

【中文标题】如何在 tkinter Text 小部件中突出显示文本【英文标题】:How to highlight text in a tkinter Text widget 【发布时间】:2010-09-23 19:03:08 【问题描述】:

我想知道如何根据某些模式改变某些单词和表达的样式。

我正在使用Tkinter.Text 小部件,但我不确定如何做这样的事情(与文本编辑器中的语法突出显示相同的想法)。即使这是用于此目的的正确小部件,我也不确定。

【问题讨论】:

这是正确的小部件。看看idle 做了什么。 @tzot 您至少可以更好地指示应该看到哪些文件。 idlelib 包含许多文件和模块等,在我看来,如果没有真正的文档,或者没有太多经验的话,很难找到一些东西。我先带领本站用户看这篇文章:docs.python.org/3.5/library/idle.html 【参考方案1】:

这是用于这些目的的正确小部件。基本概念是,您将属性分配给标签,并将标签应用于小部件中的文本范围。您可以使用文本小部件的 search 命令来查找与您的模式匹配的字符串,这将为您返回足够的信息,将标签应用于匹配的范围。

有关如何将标签应用于文本的示例,请参阅我对问题Advanced Tkinter text box? 的回答。这不是您想要做的,但它显示了基本概念。

以下是如何扩展 Text 类以包含用于突出显示与模式匹配的文本的方法的示例。

在此代码中,模式必须是字符串,不能是已编译的正则表达式。此外,模式必须遵守Tcl's syntax rules for regular expressions。

class CustomText(tk.Text):
    '''A text widget with a new method, highlight_pattern()

    example:

    text = CustomText()
    text.tag_configure("red", foreground="#ff0000")
    text.highlight_pattern("this should be red", "red")

    The highlight_pattern method is a simplified python
    version of the tcl code at http://wiki.tcl.tk/3246
    '''
    def __init__(self, *args, **kwargs):
        tk.Text.__init__(self, *args, **kwargs)

    def highlight_pattern(self, pattern, tag, start="1.0", end="end",
                          regexp=False):
        '''Apply the given tag to all text that matches the given pattern

        If 'regexp' is set to True, pattern will be treated as a regular
        expression according to Tcl's regular expression syntax.
        '''

        start = self.index(start)
        end = self.index(end)
        self.mark_set("matchStart", start)
        self.mark_set("matchEnd", start)
        self.mark_set("searchLimit", end)

        count = tk.IntVar()
        while True:
            index = self.search(pattern, "matchEnd","searchLimit",
                                count=count, regexp=regexp)
            if index == "": break
            if count.get() == 0: break # degenerate pattern which matches zero-length strings
            self.mark_set("matchStart", index)
            self.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
            self.tag_add(tag, "matchStart", "matchEnd")

【讨论】:

谢谢,这对我帮助很大!你能告诉我如何改变它,让它接受正则表达式作为模式吗? (当我尝试时,我得到TypeError: '_sre.SRE_Pattern' object has no attribute '__getitem__' @Lastalda:文本小部件search 方法接受名为regexp 的关键字参数。如果将此设置为True,则该模式将被视为正则表达式。我已更新我的答案以包含此功能。不幸的是,关于 search 方法的 tkinter 特定文档有点稀疏。如果你阅读了官方的 tk 文档,它的解释会更好一些,尽管你必须从 tcl 到 python 做一个小的心理翻译。见tcl.tk/man/tcl8.5/TkCmd/text.htm#M120 感谢您的调查。但我仍然得到同样的错误。 :( 我的正则表达式有问题吗?我使用 w.HighlightPattern(re.compile("R\d+"),"blue") 并得到错误回溯 File "C:\Python27\lib\lib-tk\Tkinter.py", line 3030, in search if pattern and pattern[0] == '-': args.append('--') TypeError: '_sre.SRE_Pattern' object has no attribute '__getitem__' @Lastalda:pattern 参数必须是字符串,而不是已编译的正则表达式。 嗯。我先尝试了,然后在它不起作用时尝试了编译版本。但现在它确实有效。无论如何,它现在正在工作。非常感谢!【参考方案2】:

你在使用 tkinter.ttk 吗?如果是这样,请先导入 tkinter.ttk,然后在导入语句列表中导入 tkinter。这对我有用。 Here's a picture

【讨论】:

与问题无关:) ...请不要发布代码图片。

以上是关于如何在 tkinter Text 小部件中突出显示文本的主要内容,如果未能解决你的问题,请参考以下文章

如何从Tkinter,Python中的Text小部件中移除焦点

如何将Tkinter Text小部件的撤消/重做历史记录复制到另一个小部件中

如何清除/删除 Tkinter Text 小部件的内容?

如何在字体更改时停止 Tkinter Text 小部件调整大小?

如何强制 tkinter 文本小部件保持在一行

你如何检查一个小部件是不是在 Tkinter 中有焦点?