简体   繁体   中英

Tagging Whole Word Based on the First Character in a Tkinter Text Widget

I'm trying to tag and highlight a whole word based on the first character. In the example below I'm searching for hashtags "#". I want to tag and highlight the subsequent characters until the next space. So the characters "#hashtag" should all be highlighted blue. The code below finds the hashtags and highlights them blue but not the subsequent characters. I assume the problem is that I'm not using "wordend" correctly in self.text_box.tag_add("hashtag{}".format(x), self.index, self.index + "wordend") but I can't figure out what I'm doing wrong.

According to effbot.org

“wordstart” and “wordend” moves the index to the beginning (end) of the current word. Words are sequences of letters, digits, and underline, or single non-space characters. http://effbot.org/tkinterbook/text.htm

Any pointers welcome.

Here is some sample code that replicates the problem:

import tkinter as tk
import tkinter.scrolledtext as St

    class Main(tk.Tk):

    def __init__(self):

        tk.Tk.__init__(self)
        self.text = "random text\nrandom text\n#hashtag random text\n#hashtag"

        self.text_box = St.ScrolledText(self)
        self.text_box.pack()

        self.text_box.insert("1.0", self.text)

        self.index = self.text_box.search("#", "1.0", stopindex=tk.END)
        x = 0
        while self.index != "":
            self.text_box.tag_add("hashtag{}".format(x), self.index, self.index + "wordend")
            self.text_box.tag_configure("hashtag{}".format(x), foreground="blue")
            self.index += "+1c"
            self.index = self.text_box.search("#", self.index, stopindex=tk.END)
            x += 1

main=Main()
main.mainloop()

From the canonical tcl/tk documentation:

A word consists of any number of adjacent characters that are letters, digits, or underscores, or a single character that is not one of these . If the display submodifier is given, this only examines non-elided characters, otherwise all characters (elided or not) are examined.

In your case the character after "3.0" is # which is "not one of these", so that single character is considered to be a word, and thus the "wordend" modifier stops after that single character.

If you want a hashtag plus the word following it to be given the tag, your second index should be of the form " line.char +1c wordend" (eg: "3.0+1c wordend") so that you look for the end of the word beginning with the first character after the hash, not beginning with the hash itself.

I got it working by changing the tag.add line to

self.text_box.tag_add("hashtag{}".format(x), self.index, (self.index + "+1c") + " wordend").

But I'm not sure why I need to add the extra character to the end index of the tag.add command? Can anyone explain?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM