首页 > 解决方案 > How do I highlight a section of text in a tkinter text widget using the index of the text to be highlighted rather than the line.col tkinter index

问题描述

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.

标签: python-3.xtkinterwidgethighlight

解决方案


您必须使用该文本小部件的col格式。但是,文本小部件支持对基本索引的修改。例如,您可以添加+ <n> characters"(或更短的+<n>c)以计算位置远离基本索引的字符。

因此,如果您想使用像 '20' 这样的传统字符串索引,则可以使用"1.0+20c"来获取第 20 个字符。


推荐阅读