Search code examples
pythontkintertagstext-widget

Python 2.7 Tkinter Tags not shown although active


I am currently developing a text editor (in Python 2.7) for a modeling language. Everything works as expected, except the behavior of tkinker in cases where many tags are added to a text widget. In order to highlight comments in the model, I use a loop which iterates over the whole text, finds each line which contains a '#' tag, collects the starting point of this symbol, and subsequently marks the whole line (starting from the #) as a comment:

def color_sl_comments(self):
    complete_text_as_lines = self.text.get('1.0', tk.END + '-1c').splitlines()
    for line in complete_text_as_lines:
        if '#' in line:
            s_l = complete_text_as_lines.index(line) + 1
            s_c = line.index('#')
            e_l = s_l
            e_c = len(line)
            self.color_comment(s_l, s_c, e_l, e_c)

def color_comment(self, sl, sc, el, ec):
    name = "comment%s.%s.%s.%s." % (sl, sc, el, ec)
    self.text.tag_add(name, "%s.%s" % (sl, sc), "%s.%s" % (el, ec))
    self.text.tag_config(name, background="white", foreground="grey")

The color of the first comments are changed as expected, but the last ones remain with the default coloring schema. However, after debugging the code, I found out that the corresponding tag is assigned to the text, i.e., the tags are all there, but the color in the window is simply not changed. The more interesting point is: If I update the corresponding comment, e.g., add a single additional character, then the comment color is shown correctly. Removing this character reverts the coloring schema and the text is no longer shown as a comment. It seems like a bug in tkinker where not all tags are shown although being there. A different part of the code does exactly the same thing, but for multi-line comments. Here, the first ML-comment is colored correctly, but the second one is not. Since the project is too large to paste it here, here a link. A sample model is located in the source dir.


Solution

  • As far as I can see, your problem seems to be with repeating lines. When two or more lines are the same, complete_text_as_lines.index(line) will return the first of them.

    Instead of using index(), use

    for number, line in enumerate(complete_text_as_lines):
    

    That way, number will always be the correct line number (after you do +1)


    Also I noticed that because you set the background to white, the selectbackground is white also which makes it impossible to see what you have selected. To have the standard highlight color selectbackground="SystemHighlight" works for me.