Search code examples
python-3.xtkinterpriority-queue

Priority of Tkinter tags


I know this is a duplicate, but the other question did not have a valid answer, and was kind of confusing

When you add a tag to a tkinter text widget, the first tag gets priority. I would prefer it if the most recent tag added got priority. In my minimum reproducible example:

import tkinter as tk

win = tk.Tk()

txt = tk.Text(win)
txt.grid(row=0, column=0)

txt.insert('1.1', 'Hello Very Worldy World!')

txt.tag_add('tagone', '1.2', '1.4')
txt.tag_config('tagone', foreground='yellow')

txt.tag_add('tagtwo', '1.7', '1.13')
txt.tag_config('tagtwo', foreground='purple')

txt.tag_add('tagone', '1.6', '1.14')
txt.tag_config('tagone', foreground='yellow')

tk.mainloop()

If you run it, you will see that the purple tag comes into the foreground, rather than the yellow tag. Is there any way to define tag priority based on chronological order, rather than what it is using now?


Solution

  • The tag priority is based on when the tag is created, not when the tag is applied.

    From effbot:

    If you attach multiple tags to a range of text, style options from the most recently created tag override options from earlier tags. In the following example, the resulting text is blue on a yellow background.

    text.tag_config("n", background="yellow", foreground="red")
    text.tag_config("a", foreground="blue")
    text.insert(contents, ("n", "a"))
    

    Note that it doesn’t matter in which order you attach tags to a range; it’s the tag creation order that counts.

    You can change the tag priority using the tag_raise and tag_lower. If you add a text.tag_lower("a") to the above example, the text becomes red.

    Because you created tagone before tagtwo, tagtwo gets priority. You can get the behavior you expected by either giving the third range a new name (tagthree), creating tagtwo before creating tagone or using txt.tag_lower('tagtwo')/txt.tag_raise('tagone').