3

I have recently found out how to highlight syntax in tkinter text widget using idlelib. I've tried it and I thought it would be cool to use that to make my text editor app. But the problem is that the text which is coloured by the filter doesn't work when the text is selected by the user. This below is a small example of what I am trying to achieve:

from tkinter import *
from idlelib.colorizer import ColorDelegator
from idlelib.percolator import Percolator

root = Tk()

txt = Text(root, font=("Courier", 20))
txt.pack()

cdg = ColorDelegator()

cdg.tagdefs['COMMENT'] = {'foreground': '#FF0000', 'background': '#FFFFFF'}
cdg.tagdefs['KEYWORD'] = {'foreground': '#007F00', 'background': '#FFFFFF'}
cdg.tagdefs['BUILTIN'] = {'foreground': '#7F7F00', 'background': '#FFFFFF'}
cdg.tagdefs['STRING'] = {'foreground': '#7F3F00', 'background': '#FFFFFF'}
cdg.tagdefs['DEFINITION'] = {'foreground': '#007F7F', 'background': '#FFFFFF'}

Percolator(txt).insertfilter(cdg)

root.mainloop()

Expected Result (Just a screenshot from the IDE I am using, I want the colour to still be visible when its selected):

enter image description here

Actual Result (You can see that the selected text 't ("Hello Wor' is black but I don't want it to be black, I want it to be what it is):

enter image description here

So my aim is to NOT change the foreground colour of the selected text regardless of what colour it is tagged with. Thanks in advance.

ss3387
  • 299
  • 3
  • 19
  • 2
    Try adding `txt.tag_config("sel", foreground="")`. That should reset the `"foreground"` option on the `"sel"` tag which is added when you select text. I think that for some reason `idlelib` adds a foreground to the `"sel"` tag. – TheLizzard Oct 01 '22 at 07:26
  • @TheLizzard it works! thank you so much! I didn't know it could be done by just 1 line of code. Maybe that is the reason why it works for tags we created and not for idlelib now everything makes sense. Thank you so much. I think you can post it as an answer now – ss3387 Oct 01 '22 at 09:30
  • I am looking at exactly what is going on with `idlelib`. When I find out, I will write a proper answer. – TheLizzard Oct 01 '22 at 10:50
  • @TheLizzard, I think I found it. In `colorizer.py` in the class `ColorDelegator` and the function `config_colors` it does `self.tag_raise('sel')` so that it gave a higher priority to the tag 'sel'. So if there is more priority to the tag 'sel' then its going to ignore whatever the color of the normal thing is. – ss3387 Oct 01 '22 at 10:58
  • How did I miss that the default `foreground` for the `"sel"` tag isn't blank... So yes raising `"sel"` would mean that it's `foreground` is taken into account instead of the other tags – TheLizzard Oct 01 '22 at 11:07

1 Answers1

1

So OP is right. ColorDelegator calls self.tag_raise('sel') which puts the tag at the top so the foreground option of the "sel" tag is taken instead of the other tags.

If you do this:

import tkinter as tk

root = tk.Tk()
txt = tk.Text(root)
txt.pack()
print(txt.tag_config("sel")["foreground"]) # Outputs ('foreground', '', '', '', '#000000')

You can see that tkinter or tcl has set a default foreground option for the "sel" tag. To remove it use txt.tag_config("sel", foreground="").

TheLizzard
  • 7,248
  • 2
  • 11
  • 31