Python Forum

Full Version: color a string of characters in tkinter
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi,
I would like to color two character strings written in a Text tkinter widget according to the status of a check button (check mark or no check).
for example, suppose that I have two variables A and B; each contains a string of characters such that:

A="approved operation"
B="not approved operation"

and that when the checkbutton button is:

* checkmarked, it is the variable A which is written with a green color.
* not checkmarked, it is the chain B which is written with a brown color

if I click on the save button, a paragraph with the heading is the variable A, or the variable B (depending on the state of the checkbuton) is added to the content of the tkinter Text widget.

As you see these strings of character (A or B) are not fixed on a precise line in the content of the Text widget , but are written each time I click on the button save

thanks for help
Requires python 3.6 or newer

This code will allow you to color and set background for any portion of any line
def highlight_text(tag_name, lineno, start_char, end_char, bg_color=None, fg_color=None):
    txtwidget.tag_add(tag_name, f'{lineno}.{start_char}', f'{lineno}.{end_char}')
    txtwidget.tag_config(tag_name, background=bg_color, foreground=fg_color)
And used in example:
import tkinter as tk

data = """'This is line 1.'
'This is line 2.'
'Yet another line.'
'And finally the last line.'
"""
root = tk.Tk()

txtwidget = tk.Text(root)
for line in data:
    txtwidget.insert(tk.END, line)
txtwidget.pack(expand=1, fill=tk.BOTH)

# adding a tag to a part of text specifying the indices
def highlight_text(tag_name, lineno, start_char, end_char, bg_color=None, fg_color=None):
    txtwidget.tag_add(tag_name, f'{lineno}.{start_char}', f'{lineno}.{end_char}')
    txtwidget.tag_config(tag_name, background=bg_color, foreground=fg_color)
    
highlight_text(tag_name='tag1', lineno=1, start_char=1, end_char=5, fg_color='red')
highlight_text(lineno=1, start_char=9, end_char=15, bg_color="black", fg_color='yellow', tag_name='zingo')

root.mainloop()
results:
[attachment=588]

** Note ** added as edit --> This can be modified to work with older versions by replacing f-string's.
thanks for the code
I will check it and try to understand it

I modify your code and add another data with thw same first sentence
import tkinter as tk
 
data = """'This is line 1.'
'This is line 2.'
'Yet another line.'
'And finally the last line.'
"""

data2 = """'This is line 1.'

'Yet another line.'

"""
root = tk.Tk()
 
txtwidget = tk.Text(root)

for line in data:
    txtwidget.insert(tk.END, line)
txtwidget.pack(expand=1, fill=tk.BOTH)

for line2 in data2:
    txtwidget.insert(tk.END, line2)
txtwidget.pack(expand=1, fill=tk.BOTH)
 
# adding a tag to a part of text specifying the indices
def highlight_text(tag_name, lineno, start_char, end_char, bg_color=None, fg_color=None):
    txtwidget.tag_add(tag_name, f'{lineno}.{start_char}', f'{lineno}.{end_char}')
    txtwidget.tag_config(tag_name, background=bg_color, foreground=fg_color)
     
# text.tag_add("start", "1.8", "1.13")
# text.tag_config("start", background="black", foreground="yellow")
 
highlight_text(tag_name='tag1', lineno=1, start_char=1, end_char=5, fg_color='red')
highlight_text(lineno=1, start_char=9, end_char=15, bg_color="black", fg_color='yellow', tag_name='zingo')
 
 
root.mainloop()
my second data is not colored like the first data
Quote:my second data is not colored like the first data
Spend a bit of effort and try to understand this code.
lines 34 and 35 are a sample only of the test data at top.
you need to call highlight_text for each item you want to colorize, giving all required paramaters (except one of optional bg_color and fg_color only needs to be supplied). but you need:
  • tag_name
  • lineno - which line number
  • start_char - starting chanacter position (from start of line)
  • end_char - ending characyer position (from start of line)
  • bg_color - color of background if supplied
  • AND/OR
  • fg_color - color of foreground if supplied
Note you can use hex values for colors like: #ffcc66 example:
highlight_text(lineno=1, start_char=9, end_char=15, bg_color="black", fg_color='#ffcc66', tag_name='zingo')
yyou can choose these colors here: https://www.w3schools.com/colors/colors_names.asp
for information, the content of the Text widget is changing every time when I click on the button "add", the new information is added with the old information.
so the number of the line where I find my color string is fixed .

therefore how am I going to define " lineno - which line number " with the content of the Text widget that is not fixed
then you must search for it by content.
There's no way to colorize something without knowing what and where it is located.
The only part of the example I posted that you need for your program is the function:
# adding a tag to a part of text specifying the indices
def highlight_text(tag_name, lineno, start_char, end_char, bg_color=None, fg_color=None):
    txtwidget.tag_add(tag_name, f'{lineno}.{start_char}', f'{lineno}.{end_char}')
    txtwidget.tag_config(tag_name, background=bg_color, foreground=fg_color)
There must be an anchor you can search for, right?
in html with css, there is synthaxe span and class:

<span class = "mycolor"> Hello </ span>

<style>
.mycolor {color: # FF0000; }

</style>

there is something like that in python