0
votes

I am trying to highlight a portion of the text in a tkinter text widget. This is easy to do if you know the line.col index of the text you wish to highlight. However, the index of the text portion I would like to highlight is in the typical string index format (an integer) rather than the line.col index format that tkinter requires. Below is some simplified code that shows what I am trying to accomplish:

from tkinter import *

class textHighlightWidget(Frame):
   def __init__(self, parent=None):
       Frame.__init__(self, parent)
       self.pack(expand=YES, fill=BOTH)
       self.makeWidgets()

    def text_for_widget(self):
        return 'This is a cat. This is a dog \n This is a cat and a 
dog. \n' \
               'This is a horse'

    def highlight_text_index(self):
        sent_beg_index = 20
        sent_end_index = 40
        self.text1.tag_add('sel', sent_beg_index, sent_end_index)

    def highlight_text_line_col(self):
        sent_beg_index = '1.0'
        sent_end_index = '2.5'
        self.text1.tag_add('sel', sent_beg_index, sent_end_index)

    def highlight_text_convert_index(self):
        sent_beg_index = 20
        sent_end_index = 40
        formatted_sent_beg_index = self.text1.index(sent_beg_index)
        formatted_sent_end_index = self.text1.index(sent_end_index)
        self.text1.tag_add('sel', formatted_sent_beg_index, 
formatted_sent_end_index)

    def makeWidgets(self):
        #self.btn1 = Button(self, text='Highlight Text', 
command=self.highlight_text_index)
        #self.btn1 = Button(self, text='Highlight Text', 
command=self.highlight_text_line_col)
        self.btn1 = Button(self, text='Highlight Text', 
command=self.highlight_text_convert_index)
        self.btn1.grid(row=0, column=0)
        self.text1 = Text(self, height=4, width=30)
        self.text1.tag_configure("center", justify='center')
        self.text1.insert('end', self.text_for_widget(), 'center')
        self.text1.grid(row=0, column=1)


if __name__ == '__main__':
    root = Tk()
    app = textHighlightWidget(root)
    root.mainloop()

I have three different highlight_text defs. The first (highlight_text_index) uses just the integer indexes of the start and end character of the portion of text I would like to highlight. When I run the code with this def I get the following error:

_tkinter.TclError: bad text index "20"

The second highlight_text def (highlight_text_line_col) uses the line.col format that tkinter expects. This method highlights the specified portion of the text however I do not know how to convert my integer indexes to the line.col index format so this second highlight_text def only shows me that the tag_add command is the correct command to use but doesn't allow me to select my desired portion of text for highlighting.

The third highlight_text def (highlight_text_convert_index) uses tkinter's text index method to convert an index to the line.col format that tkinter expects. This seems to me like it should work but again I get the same error message I got with the first highlight_text def:

_tkinter.TclError: bad text index "20"

If anybody knows how to highlight text within a tkinter text widget directly form the integer form of the index or how to convert the index to the line.col format tkinter expects I would appreciate the help.

1

1 Answers

1
votes

You must use the line.col format for the text widget. However, the text widget supports modifications on a base index. For example, you can add + <n> characters" (or the shorter +<n>c) in order to compute a position that is characters away from the base index.

Thus, if you want to use a traditional string index like '20', you could use "1.0+20c" to get the 20th character.