python-3.xtkintersyntax-highlightingpygmentstkinter-text

is there a way to bind key press to root without disturbing default binds in tkinter


I am trying to add syntax highlighting to the text widget in tkinter i am using the code from another stack overflow question Pygments syntax highlighter in python tkinter text widget i binded the function for syntax hyghlighting to the root but the problem is that all the other default binds like CTRL A stops working. They work fine if i bind it to the text widget but the last entered letter doesnt get highlighted. Heres the code(i am new to programming so there might be many silly mistakes)

from tkinter import *
from pygments import lex
from pygments.lexers import PythonLexer

def test(e):
    txt.mark_set("range_start", "1.0")
    data = txt.get("1.0", "end")
    for tag in txt.tag_names():
        txt.tag_remove(tag,"1.0","end")
    for token, content in lex(data, PythonLexer()):
        txt.mark_set("range_end", "range_start + %dc" % len(content))
        txt.tag_add(str(token), "range_start", "range_end")
        txt.mark_set("range_start", "range_end")

root=Tk()
txt=Text(root)
txt.pack(expand='yes')
txt.tag_configure("Token.Comment.Single", foreground='red')
root.bind('<Any-KeyPress>',test)
root.mainloop()

Solution

  • The problem isn't because you're replacing the default bindings. That's simply not how bindings work in tkinter. There are no bindings directly tied to the root widget or any other specific widget. Default bindings are implemented as bindings on "all" or on widget classes, not individual widgets.

    They work fine if i bind it to the text widget but the last entered letter doesnt get highlighted.

    That is because a binding on a widget happens before the default bindings. So, if you type "a", your code will be called before the code that inserts the letter "a".

    There is a question on this site related to the order in which events are processed. While the answer is tied to an Entry widget, the exact same concept applies to all widgets. See this answer to the question Basic query regarding bindtags in tkinter