Question

I'm writing a small utility in Python that does some pattern matching of text. Text that matches the pattern the user has entered gets highlighted yellow.

I'm achieving this using a Tkinter Text widget, and setting up a tag on the Text widget named "match" that gives any text with the tag name "match" a yellow background.

This all looks nice, except when I try to highlight the text using the mouse (e.g. when wanting to copy/paste). When I highlight the text with the mouse, any of the tagged text that already has a yellow background retains its yellow background, even after being highlighted. This means you can't properly read the text when it's been highlighted by the mouse, as the white text (text goes white when highlighted by mouse) on a yellow background provides bad contrast.

What I would like to happen is that, when I highlight the text in the Text widget using the mouse, all of the text gets the standard blue background color/white text color that you'd normally get on a Windows machine when highlighting a section of text.

Here's a quick code snippet to demonstrate what I mean:

from tkinter import *

root = Tk()

w = Text(root)
w.tag_config("match",background="yellow")
w.config(highlightbackground="red")
w.pack()
w.insert(INSERT,"some non-matching text.")
w.insert(INSERT,"some matching text.","match")

root.mainloop()

If you run this, and then highlight all of the text in the Text widget, you'll see that the text with the yellow background becomes very hard to read.

Note that in the code snippet above I've tried changing the highlight background color using:

w.config(highlightbackground="red")

But this hasn't worked.

Was it helpful?

Solution

Tags have priority. Tags with a high priority have preference over those that have a lower priority. When you select a range of text it is given the tag "sel". You simply need to raise the priority of the "sel" tag to be above the priority of your "match" tag:

w.tag_raise("sel")

Alex Martelli writes in the comments "it will do the OP absoluely [sic] no good if he sets highlightbackground instead of selectbackground" but that is incorrect. While he is correct that setting highlightbackground has nothing to do with the selection, it has no bearing on this solution.

Raising the priority of the "sel" tag works with the code in the original question, with or without the addition of the code that sets highlightbackground.

For more information on the text widget check out the text widget tutorial on tkdocs.com. It has code examples in Tcl, Python, Ruby and Perl.

OTHER TIPS

I think you need to set selectbackground, not highlightbackground which means something completely different (the bg color for the "highlight rectangle" drawn around a widget when it gets focus). However, I believe the sel pseudo-tag (representing the selection, which is what I think you're calling "the highlight") is "below" user-created tags such as your match; if so, then the bg color for the user-created tag would show, not the bg color for the sel pseudo-tag (aka selectbackground).

With Tk 8.5 you could remedy that by binding to the <Selection> pseudo-event a function that places an appropriately colored user tag "on top" of pseudo-tag sel; however, there is no such event in Tk 8.4, which is what most likely you're using today. TK's docs say that 8.5 comes with Python 3.1 on the ActiveState distribution of Python for Windows; unfortunately there are only "TODO" placeholders regarding other platforms or other versions of Python -- I don't know how to best obtain Tk 8.5 for the specific platform(s) and python version(s) of your interest.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top