总是 tkinter 文本 highlight_patern 不工作

Always tkinter Text highlight_patern not working

我用过 this question,但以后好像不能再用了。我稍后用 root.after 调用它,但它什么也没做。
我的代码是:

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")
root = Tk()
T = CustomText(root).pack()
T.tag_configure("red",foreground="#ff0000")
def highlighttext():
    T.highlight_pattern('hello', 'red')
    root.after(10, highlighttext)
root.after(10, highlighttext)
root.mainloop()

感谢您的帮助。

修复

  • widget.pack() returns None,因此您的 T 变量将为 None。您需要在初始化后打包您的小部件。
  • 一个名为 higlighttext 的函数不存在,请修复 highlighttext 方法中的 after 方法。
  • 删除 highlighttext 方法之外的 after 方法。

建议

使用 after 方法突出显示单词似乎效率低下,可能无法按预期工作。大多数代码编辑器都使用文本小部件生成的文本修改事件。

下面 <<TextModified>> 事件的代码取自 之前在 Whosebug 中提出的一个问题。

import tkinter as tk

class CustomText(tk.Text):
    """A text widget with a new method, highlight_pattern()
    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)

        # 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

    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
            # degenerate pattern which matches zero-length strings
            if count.get() == 0: break 
            self.mark_set("matchStart", index)
            self.mark_set("matchEnd", "%s+%sc" % (index, count.get()))
            self.tag_add(tag, "matchStart", "matchEnd")

root = tk.Tk()

text = CustomText()
text.pack()
text.tag_configure("red", foreground="#ff0000")

def highlighttext(*args):
    text.highlight_pattern("hello", "red")

text.bind("<<TextModified>>", highlighttext)

root.mainloop()

完整代码

应用所有修复后,您的代码将如下所示

import tkinter as tk

class CustomText(tk.Text):
    '''A text widget with a new method, highlight_pattern()
    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")

root = tk.Tk()

T = CustomText(root)
T.pack()
T.tag_configure("red",foreground="#ff0000")

def highlighttext():
    T.highlight_pattern('hello', 'red')
    root.after(1000, highlighttext)

highlighttext()
root.mainloop()